@astrasyncai/verification-gateway 2.4.9 → 2.4.10

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/access-levels.ts","../src/version.ts","../src/verify.ts","../src/adapters/express.ts","../src/transport/http.ts","../src/pdlss-pre-check.ts","../src/adapters/nextjs.ts","../src/adapters/sdk.ts","../src/transport/index.ts","../src/transport/a2a.ts","../src/transport/mcp.ts","../src/transport/purpose-mapping.ts","../src/transport/transaction-value.ts","../src/transport/rfc9421.ts","../src/transport/rfc9421-verify.ts","../src/transport/ucp.ts","../src/transport/acp.ts","../src/transport/vi.ts","../src/transport/stripe-webhook.ts","../src/transport/constraint-eval.ts","../src/transport/identity-binding.ts","../src/transport/ap2.ts","../src/transport/ap2-verify.ts","../src/transport/acp-verify.ts","../src/transport/mpp.ts","../src/transport/mpp-verify.ts","../src/transport/x402.ts","../src/transport/vi-verify.ts","../src/transport/commerce-pipeline.ts","../src/transport/extractor-registry.ts","../src/transport/registry/visa.ts","../src/transport/registry/mastercard.ts","../src/transport/registry/web-bot-auth.ts","../src/transport/mcp-server.ts","../src/adapters/mcp.ts","../src/registration/errors.ts","../src/registration/api.ts","../src/registration/guidance.ts","../src/agent/index.ts","../src/agent/errors.ts","../src/agent/client.ts","../src/agent/challenge-handler.ts","../src/agent/pdlss-formatter.ts","../src/agent/decision-client.ts"],"sourcesContent":["/**\n * AstraSync Universal Verification Gateway\n *\n * A single verification library for any system to verify AI agents.\n * One codebase, multiple deployment targets.\n *\n * @example\n * ```typescript\n * import { verify, extractCredentials } from '@astrasyncai/verification-gateway';\n *\n * const credentials = extractCredentials(request.headers);\n * const result = await verify(config, { credentials, purpose: 'data-access' });\n *\n * if (result.identityVerified && result.policyAllowed && result.accessLevel !== 'none') {\n * // Grant access based on result.accessLevel\n * }\n *\n * // Or map to HTTP status codes directly:\n * if (!result.identityVerified) return res.status(401).json({ ... }); // re-auth\n * if (!result.policyAllowed) return res.status(403).json({ ... }); // step up / update PDLSS\n * ```\n *\n * @packageDocumentation\n */\n\n// Core types\nexport type {\n TrustLevel,\n AccessLevel,\n CounterpartyType,\n AgentCredentials,\n GatewayConfig,\n VerifiedAgent,\n VerifiedDeveloper,\n VerifiedOrganization,\n PDLSSInfo,\n GuidanceInfo,\n VerificationResult,\n VerificationRequest,\n RouteAccessConfig,\n ExpressMiddlewareOptions,\n NextJsMiddlewareOptions,\n SDKOptions,\n CommerceShieldProps,\n // Handshake Protocol v10 types\n TokenGuidance,\n RuntimeChallengeResult,\n EnhancedVerificationResult,\n AstraSyncCredentials,\n ProtocolTransport,\n} from './types';\n\n// Access level utilities\nexport {\n ACCESS_LEVEL_HIERARCHY,\n ACCESS_LEVEL_DESCRIPTIONS,\n DEFAULT_TRUST_THRESHOLDS,\n TRUST_LEVEL_RANGES,\n getTrustLevel,\n hasMinimumAccess,\n getAccessLevelForScore,\n determineAccessLevel,\n getCapabilities,\n} from './access-levels';\n\nexport type { AccessCapabilities } from './access-levels';\n\n// Core verification functions\nexport { verify, quickVerify, extractCredentials, hasCredentials, clearCache } from './verify';\n\n// Re-export adapters for convenience (tree-shakeable)\nexport * as express from './adapters/express';\nexport * as nextjs from './adapters/nextjs';\nexport * as sdk from './adapters/sdk';\n\n// Cross-protocol transport adapters\nexport * as transport from './transport';\n\n// Round-16 — flat re-exports of MCP bridge helpers so consumers using\n// `moduleResolution: \"node\"` can import without the subpath form (subpaths\n// `/mcp`, `/transport` require node16 / nodenext / bundler resolution).\nexport { createMcpMiddleware } from './adapters/mcp';\nexport type { McpMiddlewareOptions } from './adapters/mcp';\nexport { extractMcpCredentials, setMcpMeta } from './transport/mcp';\n\n// Round-17 — flat re-exports of the registration API so consumers using\n// `moduleResolution: \"node\"` (e.g. apps/mcp-server) can import without the\n// `/registration` subpath form. Same pattern as the Round-16 MCP re-exports.\n// Round-18 (B3b) — `buildGuidance` joins the surface so partner wrappers can\n// produce the credentials-required envelope without inlining the five-step\n// boilerplate.\nexport {\n AstraSync,\n AstraSyncError,\n AuthenticationError,\n KYDRequiredError,\n RegistrationDeniedError,\n RegistrationExpiredError,\n RegistrationTimeoutError,\n buildGuidance,\n} from './registration';\nexport type {\n AstraSyncConfig,\n RegisterOptions,\n RegisterResult,\n WaitForApprovalOptions,\n PendingRegistrationResponse,\n PollRegistrationResult,\n RegistrationResponse,\n AgentRecord,\n VerifyResponse,\n HealthResponse,\n PDLSSConfig,\n PDLSSPurpose,\n PDLSSDuration,\n PDLSSLimits,\n PDLSSScope,\n PDLSSSelfInstantiation,\n ModelConfig,\n FrameworkConfig,\n AgentProtocol,\n GuidanceEnvelope,\n BuildGuidanceParams,\n} from './registration';\n\n// Agent-side SDK\nexport * as agent from './agent';\nexport { AgentClient } from './agent/client';\nexport { ChallengeHandler } from './agent/challenge-handler';\nexport { recordDecision } from './agent/decision-client';\n\n// Version\nexport const VERSION = '2.0.0';\n","/**\n * AstraSync Universal Verification Gateway - Access Level Definitions\n *\n * Defines the hierarchy and capabilities of each access level.\n *\n * v2.3.9 (defect #30): renamed `'guidance'` band → `'restricted'`. See\n * `types.ts` AccessLevel for the rationale (value-name collision with the\n * `guidance: {...}` help-payload object on VerificationResult).\n */\n\nimport type { AccessLevel, TrustLevel } from './types';\n\n/**\n * Access level hierarchy (higher number = more access)\n */\nexport const ACCESS_LEVEL_HIERARCHY: Record<AccessLevel, number> = {\n none: 0,\n restricted: 1,\n 'read-only': 2,\n standard: 3,\n full: 4,\n internal: 5,\n};\n\n/**\n * Access level descriptions for UI\n */\nexport const ACCESS_LEVEL_DESCRIPTIONS: Record<AccessLevel, string> = {\n none: 'No access - credentials required',\n restricted: 'Restricted access - registration prompt only',\n 'read-only': 'Read-only access - can browse but not modify',\n standard: 'Standard access - normal operations per PDLSS policy',\n full: 'Full access - all operations for high-trust agents',\n internal: 'Internal access - organization member privileges',\n};\n\n/**\n * Default trust score thresholds for access levels\n */\nexport const DEFAULT_TRUST_THRESHOLDS: Record<AccessLevel, number> = {\n none: 0,\n restricted: 0,\n 'read-only': 20,\n standard: 40,\n full: 70,\n internal: 0, // Internal is based on org membership, not score\n};\n\n/**\n * Trust level score ranges\n */\nexport const TRUST_LEVEL_RANGES: Record<TrustLevel, { min: number; max: number }> = {\n BRONZE: { min: 0, max: 39 },\n SILVER: { min: 40, max: 59 },\n GOLD: { min: 60, max: 79 },\n PLATINUM: { min: 80, max: 100 },\n};\n\n/**\n * Determine trust level from score\n */\nexport function getTrustLevel(score: number): TrustLevel {\n if (score >= 80) return 'PLATINUM';\n if (score >= 60) return 'GOLD';\n if (score >= 40) return 'SILVER';\n return 'BRONZE';\n}\n\n/**\n * Check if access level A is greater than or equal to access level B\n */\nexport function hasMinimumAccess(actual: AccessLevel, required: AccessLevel): boolean {\n return ACCESS_LEVEL_HIERARCHY[actual] >= ACCESS_LEVEL_HIERARCHY[required];\n}\n\n/**\n * Get the highest access level for a given trust score\n */\nexport function getAccessLevelForScore(\n trustScore: number,\n thresholds: Record<AccessLevel, number> = DEFAULT_TRUST_THRESHOLDS\n): AccessLevel {\n if (trustScore >= thresholds.full) return 'full';\n if (trustScore >= thresholds.standard) return 'standard';\n if (trustScore >= thresholds['read-only']) return 'read-only';\n return 'restricted';\n}\n\n/**\n * Determine access level from verification result.\n *\n * v2.3.9 (defect #30): unverified callers now return `'none'` (was\n * `'guidance'`). Denials grant zero — never a positive band.\n */\nexport function determineAccessLevel(\n verified: boolean,\n trustScore: number,\n isOrgMember: boolean,\n customThresholds?: Partial<Record<AccessLevel, number>>\n): AccessLevel {\n if (!verified) {\n return 'none';\n }\n\n if (isOrgMember) {\n return 'internal';\n }\n\n const thresholds = {\n ...DEFAULT_TRUST_THRESHOLDS,\n ...customThresholds,\n };\n\n return getAccessLevelForScore(trustScore, thresholds);\n}\n\n/**\n * Access capabilities per level\n */\nexport interface AccessCapabilities {\n canRead: boolean;\n canWrite: boolean;\n canDelete: boolean;\n canAdmin: boolean;\n canAccessInternal: boolean;\n maxTransactionValue?: number;\n allowedPurposes?: string[];\n}\n\n/**\n * Get capabilities for an access level\n */\nexport function getCapabilities(accessLevel: AccessLevel): AccessCapabilities {\n switch (accessLevel) {\n case 'none':\n return {\n canRead: false,\n canWrite: false,\n canDelete: false,\n canAdmin: false,\n canAccessInternal: false,\n };\n case 'restricted':\n return {\n canRead: false,\n canWrite: false,\n canDelete: false,\n canAdmin: false,\n canAccessInternal: false,\n };\n case 'read-only':\n return {\n canRead: true,\n canWrite: false,\n canDelete: false,\n canAdmin: false,\n canAccessInternal: false,\n };\n case 'standard':\n return {\n canRead: true,\n canWrite: true,\n canDelete: false,\n canAdmin: false,\n canAccessInternal: false,\n };\n case 'full':\n return {\n canRead: true,\n canWrite: true,\n canDelete: true,\n canAdmin: false,\n canAccessInternal: false,\n };\n case 'internal':\n return {\n canRead: true,\n canWrite: true,\n canDelete: true,\n canAdmin: true,\n canAccessInternal: true,\n };\n default:\n return {\n canRead: false,\n canWrite: false,\n canDelete: false,\n canAdmin: false,\n canAccessInternal: false,\n };\n }\n}\n","/**\n * Round-13 (F14 closure / R13-7): single source-of-truth for the SDK's\n * package version emitted on verify-access bodies (and any future\n * telemetry). Bumped alongside `package.json#version` on every release.\n *\n * Why a constant rather than `import pkg from '../package.json'`:\n * - `tsconfig.json` sets `rootDir: ./src`; importing the sibling\n * package.json fails the build with \"outside rootDir\".\n * - Build-time string replacement (tsup `define`, esbuild banner, etc.)\n * adds toolchain coupling for a trivial gain.\n * - Embedded readonly constant works in every environment (Node, browser,\n * bundlers, Deno) without runtime fs / network access.\n *\n * Release discipline: a CI lint can grep `package.json#version` against\n * this constant if the two ever diverge in the wild. Round-13 manual bump\n * is fine — bumping both in the release-ceremony commit keeps them\n * lockstep.\n */\nexport const SDK_VERSION = '2.4.9';\n","/**\n * AstraSync Universal Verification Gateway - Core Verification Logic\n *\n * This module handles the core verification logic, calling the AstraSync API\n * and processing the response into a standardized VerificationResult.\n */\n\nimport type {\n GatewayConfig,\n AgentCredentials,\n VerificationRequest,\n VerificationResult,\n VerifiedAgent,\n VerifiedDeveloper,\n VerifiedOrganization,\n GuidanceInfo,\n AccessLevel,\n EnhancedVerificationResult,\n TokenGuidance,\n RuntimeChallengeResult,\n} from './types';\nimport { getTrustLevel, ACCESS_LEVEL_HIERARCHY } from './access-levels';\nimport { SDK_VERSION } from './version';\n\n/**\n * Default configuration values\n *\n * apiBaseUrl matches the OpenAPI authoritative server (https://astrasync.ai/api\n * for prod, https://staging.astrasync.ai/api for staging). Always include the\n * /api path prefix when overriding — registration / docs URLs are derived by\n * stripping it.\n */\nconst DEFAULT_CONFIG: Partial<GatewayConfig> = {\n apiBaseUrl: 'https://astrasync.ai/api',\n // v2.3.9 (defect #30): default for unconfigured callers is `'none'` (no\n // access). Pre-rename this defaulted to `'guidance'`, which combined with\n // a route gated at `'guidance'` to silently let unverified traffic\n // through (`hasMinimumAccess('guidance', 'guidance') === true`).\n defaultAccessLevel: 'none',\n // minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.\n cacheTtl: 300, // 5 minutes\n debug: false,\n};\n\n/**\n * Init self-test state. Fires once per process on first verify() call to warn\n * if apiBaseUrl is pointing at the wrong host (e.g. a marketing site that\n * 200s with text/html instead of the API).\n */\nlet initCheckPerformed = false;\n\n/** One-shot guard for v2.3.0 deprecation warning. */\nlet deprecationWarningShown = false;\n\nasync function performInitCheck(apiBaseUrl: string, debug?: boolean): Promise<void> {\n initCheckPerformed = true;\n try {\n const probeUrl = `${apiBaseUrl}/agents/verify-access`;\n // HEAD mirrors GET semantics (running the full request pipeline without a\n // body) so the response carries the same content-type the marketing 404\n // would return. OPTIONS often gets short-circuited by CORS-preflight\n // handlers and returns no content-type, defeating the check.\n const response = await fetch(probeUrl, { method: 'HEAD' });\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.startsWith('text/html')) {\n console.warn(\n `[VerificationGateway] apiBaseUrl '${apiBaseUrl}' returned HTML (content-type: ${contentType}). ` +\n `This usually means apiBaseUrl is pointing at a marketing site instead of the API. ` +\n `Expected: 'https://astrasync.ai/api' (prod) or 'https://staging.astrasync.ai/api' (staging). ` +\n `Set disableInitChecks: true on GatewayConfig to silence this warning.`\n );\n } else if (debug) {\n console.log(\n `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`\n );\n }\n } catch (err) {\n if (debug) {\n console.log(`[VerificationGateway] init check failed (non-blocking): ${String(err)}`);\n }\n }\n}\n\n/**\n * Simple in-memory cache for verification results\n */\nconst verificationCache = new Map<string, { result: VerificationResult; expiresAt: number }>();\n\n/**\n * Generate cache key from credentials\n */\nfunction getCacheKey(credentials: AgentCredentials): string {\n return `${credentials.astraId || ''}-${credentials.apiKey || ''}-${credentials.jwt || ''}`;\n}\n\n/**\n * Check if cached result is still valid\n */\nfunction getCachedResult(credentials: AgentCredentials): VerificationResult | null {\n const key = getCacheKey(credentials);\n const cached = verificationCache.get(key);\n\n if (cached && cached.expiresAt > Date.now()) {\n return cached.result;\n }\n\n if (cached) {\n verificationCache.delete(key);\n }\n\n return null;\n}\n\n/**\n * Cache a verification result\n */\nfunction cacheResult(\n credentials: AgentCredentials,\n result: VerificationResult,\n ttlSeconds: number\n): void {\n const key = getCacheKey(credentials);\n verificationCache.set(key, {\n result,\n expiresAt: Date.now() + ttlSeconds * 1000,\n });\n}\n\n/**\n * Clear the verification cache\n */\nexport function clearCache(): void {\n verificationCache.clear();\n}\n\n/**\n * Extract agent credentials from various sources\n */\nexport function extractCredentials(\n headers: Record<string, string | string[] | undefined>,\n query?: Record<string, string | undefined>\n): AgentCredentials {\n const credentials: AgentCredentials = {};\n\n // Check for ASTRA-ID in headers (case-insensitive). Accepts the historical\n // X-Astra-Id name plus the X-Astra-AgentId / x-astra-agent-id alias the\n // partner asked for in #9a — both surface the same field.\n const astraIdHeader =\n headers['x-astra-id'] ||\n headers['X-Astra-Id'] ||\n headers['X-ASTRA-ID'] ||\n headers['x-astra-agentid'] ||\n headers['X-Astra-AgentId'] ||\n headers['x-astra-agent-id'] ||\n headers['X-Astra-Agent-Id'] ||\n headers['X-ASTRA-AGENT-ID'];\n if (astraIdHeader) {\n credentials.astraId = Array.isArray(astraIdHeader) ? astraIdHeader[0] : astraIdHeader;\n }\n\n // Check for API key in headers\n const apiKeyHeader = headers['x-api-key'] || headers['X-Api-Key'] || headers['X-API-KEY'];\n if (apiKeyHeader) {\n credentials.apiKey = Array.isArray(apiKeyHeader) ? apiKeyHeader[0] : apiKeyHeader;\n }\n\n // Check Authorization header for Bearer token\n const authHeader = headers['authorization'] || headers['Authorization'];\n if (authHeader) {\n const authValue = Array.isArray(authHeader) ? authHeader[0] : authHeader;\n credentials.authorizationHeader = authValue;\n\n if (authValue.startsWith('Bearer ')) {\n credentials.jwt = authValue.slice(7);\n }\n }\n\n // Check query parameters as fallback\n if (query) {\n if (query.astraId && !credentials.astraId) {\n credentials.astraId = query.astraId;\n }\n if (query.apiKey && !credentials.apiKey) {\n credentials.apiKey = query.apiKey;\n }\n }\n\n return credentials;\n}\n\n/**\n * Check if credentials are present\n */\nexport function hasCredentials(credentials: AgentCredentials): boolean {\n return !!(credentials.astraId || credentials.apiKey || credentials.jwt);\n}\n\n/**\n * Source of a synthesised guidance response. Round-10 split — the\n * `'no_credentials'` shape is the original (caller has no AstraSync\n * credentials, suggest registration). The `'api_error'` shape is for when\n * the verify-access HTTP call itself failed (5xx, network, etc.) — DON'T\n * tell a verified-but-currently-blocked partner to \"register your agent\".\n */\ntype GuidanceSource = 'no_credentials' | 'api_error';\n\n/**\n * Create guidance response for unverified agents or for API-error fallback.\n *\n * Round-10 (#47, O5): split source so the `register your agent` template\n * doesn't fire on transient backend failures. Also threads `correlationId`\n * through so adapter `onDenied` handlers can surface it on the merchant's\n * response body for log correlation.\n */\nfunction createGuidanceResponse(\n config: GatewayConfig,\n reason?: string,\n options: { source?: GuidanceSource; correlationId?: string } = {}\n): VerificationResult {\n const source = options.source ?? 'no_credentials';\n const isApiError = source === 'api_error';\n\n const guidance: GuidanceInfo = isApiError\n ? {\n message:\n 'Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.',\n registrationUrl: `${config.apiBaseUrl.replace('/api', '')}/register`,\n documentationUrl: `${config.apiBaseUrl.replace('/api', '')}/docs/agent-access`,\n steps: [\n 'Retry the request with exponential backoff',\n 'If failures persist, share the correlationId with support',\n ],\n }\n : {\n message:\n 'This service verifies AI agents before granting access. Please register your agent with AstraSync.',\n registrationUrl: `${config.apiBaseUrl.replace('/api', '')}/register`,\n documentationUrl: `${config.apiBaseUrl.replace('/api', '')}/docs/agent-access`,\n steps: [\n 'Register for an AstraSync account',\n 'Create and register your agent',\n 'Add your ASTRA-ID to request headers',\n 'Retry your request',\n ],\n };\n\n return {\n // Round-18 G4: createGuidanceResponse fires for unverified-agent path or\n // API-error fallback. Identity is not verified (no agent resolved);\n // policy is not evaluated (we never reached the gate).\n identityVerified: false,\n policyAllowed: false,\n // v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.\n // Adapters additionally short-circuit on `!identityVerified ||\n // !policyAllowed` before the gate check, but the access level still has\n // to be honest at the data layer so downstream consumers (SDK adapters\n // in other languages, custom integrations) inherit the correct\n // semantics.\n accessLevel: 'none',\n guidance,\n denialReasons: reason ? [reason] : ['No valid agent credentials provided'],\n // Round-10 (#47, O5): on API-error fallback, surface a typed failure so\n // partners (and their custom onDenied handlers) can branch on\n // dimension. Without this, the synthesised stub was indistinguishable\n // from a real policy deny.\n failures: isApiError\n ? [\n {\n dimension: 'verify_access.api_error',\n message: reason ?? 'Verification temporarily unavailable',\n guidance: guidance.message,\n },\n ]\n : undefined,\n correlationId: options.correlationId,\n verifiedAt: new Date(),\n };\n}\n\n/**\n * Call the AstraSync verify-access API\n */\nasync function callVerifyAccessAPI(\n config: GatewayConfig,\n request: VerificationRequest\n): Promise<{\n success: boolean;\n access?: {\n allowed: boolean;\n /**\n * Server-decided access level. Read verbatim — do NOT remap client-side.\n * The server resolves this from endpoint policy + agent trust score using\n * the canonical thresholds (see backend `apps/backend/src/utils/access-levels.ts`).\n */\n accessLevel?: AccessLevel;\n reason?: string;\n /**\n * Aggregated denial failures (v2.9.8+). Empty / absent when allowed.\n * Each entry is `{ dimension, message, guidance? }` — see\n * `AccessFailure` for the contract.\n */\n failures?: Array<{ dimension: string; message: string; guidance?: string }>;\n requiresStepUp?: boolean;\n requiresApproval?: boolean;\n appliedPolicy?: {\n boundaryName: string;\n policyVersion: string;\n };\n counterparty?: {\n id: string;\n name: string;\n trustScoreRequirement: number;\n };\n };\n agent?: {\n kyaAgentId: string;\n astraId: string;\n name: string;\n trustScore: number;\n trustLevel: string;\n agentStatus: string;\n blockchainStatus: string;\n };\n developer?: {\n kyaOwnerId: string;\n fullName: string;\n email: string;\n identityVerified: boolean;\n trustScore: number;\n };\n organization?: {\n name: string;\n verified: boolean;\n trustScore: number;\n };\n /**\n * Structured explanation of the verification decision. Tells the merchant\n * WHY (id verified? challenge passed? request within PDLSS? trust score?)\n * without exposing thresholds, scope lists, or other-tenant counterparty\n * membership. Empty `attestations` unless the endpoint's access policy\n * declared `required_attestations`.\n */\n verificationContext?: {\n idVerified: boolean;\n runtimeChallenge: {\n status: 'passed' | 'skipped' | 'failed' | 'timeout' | 'not_supported';\n checkedAt: string | null;\n };\n pdlssCheck: {\n result: 'within' | 'exceeded' | 'denied' | 'not_evaluated';\n purpose: 'approved' | 'denied';\n scope: 'approved' | 'denied';\n };\n dynamicTrustScore: number;\n attestations: Array<{\n type: string;\n status: 'passed' | 'failed';\n validUntil?: string;\n proofType: 'reference' | 'zkp';\n proof: string;\n }>;\n };\n error?: string;\n /**\n * Round-10 (#47, O5): when the verify-access server response carries a\n * correlationId on an error envelope, propagate it so the SDK can thread\n * it through createGuidanceResponse → adapter onDenied → merchant body.\n */\n correlationId?: string;\n}> {\n const { credentials, ...requestData } = request;\n\n // Build the request body. agentId is omitted when not provided so the\n // server treats it as an anonymous canonical-flow call (Branch A/B/C).\n const body: Record<string, unknown> = {\n ...(credentials.astraId && { agentId: credentials.astraId }),\n purpose: requestData.purpose || 'general',\n };\n\n // Add optional fields\n if (requestData.action) body.action = requestData.action;\n if (requestData.resourceType) body.resourceType = requestData.resourceType;\n if (requestData.resource) body.resource = requestData.resource;\n if (requestData.jurisdiction) body.jurisdiction = requestData.jurisdiction;\n if (requestData.transactionValue) body.transactionValue = requestData.transactionValue;\n if (requestData.currency) body.currency = requestData.currency;\n if (requestData.isSubAgentRequest) body.isSubAgentRequest = requestData.isSubAgentRequest;\n if (requestData.parentAgentId) body.parentAgentId = requestData.parentAgentId;\n if (requestData.subAgentDepth !== undefined) body.subAgentDepth = requestData.subAgentDepth;\n // Handshake Protocol v10 additions\n if (requestData.enableRuntimeChallenge)\n body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;\n if (requestData.createSession) body.createSession = requestData.createSession;\n if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;\n if (requestData.counterpartyType) body.counterpartyType = requestData.counterpartyType;\n if (requestData.counterpartyUrl) body.counterpartyUrl = requestData.counterpartyUrl;\n if (config.counterpartyId) body.counterpartyId = config.counterpartyId;\n if (requestData.runtimeChallengeOptions)\n body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;\n // Round-12 (F19): transport-vs-intent separation. MCP middleware sets\n // this to 'mcp'; non-MCP callers leave it unset.\n if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;\n\n // Round-13 (F14 closure / R13-7): emit the SDK package version on every\n // verify-access body so the backend can auto-populate `kya_counterparty.\n // sdk_version` for the calling endpoint. Body field (not User-Agent\n // header) is the canonical channel — works in Node, browser, behind\n // Cloudflare, and across SDK bundlers without environment-specific\n // header gymnastics. Backend's `validation.ts:verifyAccessSchema`\n // accepts the semver regex; the auto-pop logic is forward-only.\n body.sdkVersion = SDK_VERSION;\n\n // Forward caller metadata when present. Merges the legacy top-level\n // clientIp/userAgent into the nested block for backward compatibility.\n if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {\n const meta = {\n ...(requestData.clientIp && { sourceIp: requestData.clientIp }),\n ...(requestData.userAgent && { userAgent: requestData.userAgent }),\n ...requestData.callerMetadata,\n };\n if (Object.keys(meta).length > 0) body.callerMetadata = meta;\n }\n\n // Build headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...config.customHeaders,\n };\n\n // verify-access requires authentication. The backend's authenticate middleware\n // accepts either a JWT or an API key (starts with kya_) via `Authorization: Bearer <token>`.\n // Credential-supplied auth header (e.g. the agent's own token) takes priority.\n if (credentials.authorizationHeader) {\n headers['Authorization'] = credentials.authorizationHeader;\n } else if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n }\n // Legacy header kept for compatibility with any middleware that reads it directly.\n if (config.apiKey) {\n headers['X-API-Key'] = config.apiKey;\n }\n\n try {\n const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n const data = await response.json();\n\n // v2.3.8 (defect #29): treat 410 Gone as a deterministic deactivated-endpoint\n // signal. Older SDKs may treat any non-2xx as transient and retry; v2.3.8+\n // surfaces it as a structured denial with `reason: 'endpoint_deactivated'`\n // so callers can distinguish \"endpoint gone\" from \"endpoint denied this\".\n if (response.status === 410) {\n return {\n success: true,\n access: {\n allowed: false,\n accessLevel: 'none',\n reason: 'endpoint_deactivated',\n failures: [\n {\n dimension: 'endpoint.deactivated',\n message:\n typeof data?.message === 'string' ? data.message : 'Endpoint has been deactivated',\n guidance:\n typeof data?.guidance === 'string'\n ? data.guidance\n : 'Reactivate via POST /api/endpoints/{id}/reactivate, or update the URL on the calling agent.',\n },\n ],\n },\n };\n }\n\n if (!response.ok) {\n // Round-10 (#47, O5): propagate correlationId on the error path too if\n // the server happened to include one (some 5xx error envelopes carry\n // it). Lets the SDK pass it through to the adapter onDenied handler.\n return {\n success: false,\n error: data.message || data.error || `API returned ${response.status}`,\n correlationId: typeof data?.correlationId === 'string' ? data.correlationId : undefined,\n };\n }\n\n return data;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return {\n success: false,\n error: `Failed to call verify-access API: ${message}`,\n };\n }\n}\n\n/**\n * Main verification function\n */\nexport async function verify(\n config: GatewayConfig,\n request: VerificationRequest\n): Promise<VerificationResult> {\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\n\n // One-time init self-test — fire-and-forget, never blocks verify().\n if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {\n void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug);\n }\n\n // Deprecation warning for v2.3.0 removed config fields. Fires once per process.\n if (\n !deprecationWarningShown &&\n (config.minTrustScore !== undefined || config.minTrustScoreForFull !== undefined)\n ) {\n deprecationWarningShown = true;\n console.warn(\n '[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 ' +\n 'and have no effect. Server is now the single source of truth for access-level decisions ' +\n '(the SDK reads access.accessLevel from the verify-access response). To gate access ' +\n \"to an endpoint, configure the endpoint's trust_score_requirement server-side.\"\n );\n }\n\n // v2.3.0: anonymous traffic no longer short-circuits here. We forward the\n // request to the server with no agentId; the server applies the endpoint's\n // unverifiedAgentPolicy and returns advisory. createGuidanceResponse remains\n // as the offline fallback if the API itself fails (handled below).\n\n // Check cache first\n if (mergedConfig.cacheTtl && mergedConfig.cacheTtl > 0) {\n const cached = getCachedResult(request.credentials);\n if (cached) {\n if (mergedConfig.debug) {\n console.log('[VerificationGateway] Returning cached result');\n }\n return cached;\n }\n }\n\n // Inject counterparty info from config if not already set in request\n const enrichedRequest = { ...request };\n if (!enrichedRequest.counterpartyUrl && mergedConfig.counterpartyUrl) {\n enrichedRequest.counterpartyUrl = mergedConfig.counterpartyUrl;\n }\n if (!enrichedRequest.counterpartyType && mergedConfig.counterpartyType) {\n enrichedRequest.counterpartyType = mergedConfig.counterpartyType;\n }\n\n // Call the API\n if (mergedConfig.debug) {\n console.log('[VerificationGateway] Calling verify-access API');\n }\n\n const apiResponse = await callVerifyAccessAPI(mergedConfig, enrichedRequest);\n\n // Handle API errors\n if (!apiResponse.success) {\n // Round-10 (#47, O5): distinguish API errors from missing-credentials.\n // The previous default tagged any failure with the \"register your\n // agent\" template, which is misleading to a verified partner whose\n // verify-access call hit a 500. The `api_error` source surfaces a\n // typed `verify_access.api_error` failure entry instead.\n return createGuidanceResponse(mergedConfig, apiResponse.error, {\n source: 'api_error',\n correlationId: (apiResponse as { correlationId?: string }).correlationId,\n });\n }\n\n // Check access result\n if (!apiResponse.access?.allowed) {\n // v2.9.8 (defect M1): aggregated failures across every gate that\n // denied. Surface them on the result so the integrator can see every\n // blocker in one go instead of the previous fail-fast cascade.\n const aggregatedFailures = (apiResponse.access as Record<string, unknown> | undefined)\n ?.failures as Array<{ dimension: string; message: string; guidance?: string }> | undefined;\n // Round-18 G4: backend denied access (PDLSS or other gate); identity status\n // depends on whether the backend resolved the caller. Read from\n // verificationContext.idVerified; default false if absent (anonymous or\n // identity-fail paths land here too). policyAllowed is false by definition\n // in this branch (apiResponse.access.allowed === false).\n const idVerifiedFromBackend =\n (apiResponse.verificationContext as { idVerified?: boolean } | undefined)?.idVerified ===\n true;\n const result: EnhancedVerificationResult = {\n identityVerified: idVerifiedFromBackend,\n policyAllowed: false,\n // v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.\n // Pre-rename this hardcoded `'guidance'`, which conflated with the\n // colocated `guidance: {...}` help-payload object below and let\n // denied requests pass any route gated at `'guidance'` because\n // `hasMinimumAccess('guidance', 'guidance') === true`. Adapters now\n // ALSO short-circuit on `!identityVerified || !policyAllowed` before\n // the gate check — belt-and-braces.\n accessLevel: 'none',\n denialReasons:\n aggregatedFailures && aggregatedFailures.length > 0\n ? aggregatedFailures.map((f) => f.message)\n : apiResponse.access?.reason\n ? [apiResponse.access.reason]\n : ['Access denied'],\n failures: aggregatedFailures,\n requiresStepUp: apiResponse.access?.requiresStepUp,\n requiresApproval: apiResponse.access?.requiresApproval,\n guidance: {\n message: apiResponse.access?.reason || 'Access denied by PDLSS policy',\n registrationUrl: `${mergedConfig.apiBaseUrl?.replace('/api', '')}/register`,\n documentationUrl: `${mergedConfig.apiBaseUrl?.replace('/api', '')}/docs/pdlss`,\n },\n verifiedAt: new Date(),\n // Extract sessionId so decisions can be recorded for denials too\n sessionId: (apiResponse as Record<string, unknown>).sessionId as string | undefined,\n // v2.3.10 (defect #34, round-4): anonymous traffic has no session →\n // correlationId is the linking key for paired local_override events.\n correlationId: (apiResponse as Record<string, unknown>).correlationId as string | undefined,\n recommendation: (apiResponse as Record<string, unknown>)\n .recommendation as EnhancedVerificationResult['recommendation'],\n recommendationReasons: (apiResponse as Record<string, unknown>).recommendationReasons as\n | string[]\n | undefined,\n };\n\n return result;\n }\n\n // Build successful result\n const agent: VerifiedAgent | undefined = apiResponse.agent\n ? {\n astraId: apiResponse.agent.astraId,\n name: apiResponse.agent.name,\n trustScore: apiResponse.agent.trustScore,\n trustLevel: getTrustLevel(apiResponse.agent.trustScore),\n blockchainVerified: apiResponse.agent.blockchainStatus === 'verified',\n status: apiResponse.agent.agentStatus as VerifiedAgent['status'],\n }\n : undefined;\n\n const developer: VerifiedDeveloper | undefined = apiResponse.developer\n ? {\n astradId: apiResponse.developer.kyaOwnerId,\n name: apiResponse.developer.fullName,\n trustScore: apiResponse.developer.trustScore || 0,\n verified: apiResponse.developer.identityVerified,\n }\n : undefined;\n\n const organization: VerifiedOrganization | undefined = apiResponse.organization\n ? {\n name: apiResponse.organization.name,\n verified: apiResponse.organization.verified,\n trustScore: apiResponse.organization.trustScore,\n }\n : undefined;\n\n // Verification context — structured \"why\" the merchant gets in v2.2.4+.\n // Carries appliedPolicy (no UUIDs), pdlssCheck summary, dynamic trust score,\n // and policy-driven attestations. Replaces the old over-sharing `pdlss` block.\n const verificationContext = apiResponse.verificationContext;\n\n // Server is the single source of truth for access level. SDK reads\n // apiResponse.access.accessLevel verbatim — no client-side trust-score remap.\n // Fallback to 'standard' if the server response is missing the field (older\n // backend without the v2.3.0 contract); it covers the verified-access case.\n const accessLevel: AccessLevel = apiResponse.access?.accessLevel ?? 'standard';\n\n const result: EnhancedVerificationResult = {\n // Round-18 G4: backend allowed access. Identity is verified (we resolved\n // the caller to an agent) and policy passed all gates. Read idVerified\n // from verificationContext for symmetry with the deny branch; default true\n // on success path since `access.allowed === true` implies identity was\n // resolvable (anonymous-allow paths flow through createGuidanceResponse).\n identityVerified:\n (apiResponse.verificationContext as { idVerified?: boolean } | undefined)?.idVerified !==\n false,\n policyAllowed: true,\n accessLevel,\n agent,\n developer,\n organization,\n appliedPolicy: apiResponse.access?.appliedPolicy,\n verificationContext,\n requiresStepUp: apiResponse.access?.requiresStepUp,\n requiresApproval: apiResponse.access?.requiresApproval,\n verifiedAt: new Date(),\n cacheTtl: mergedConfig.cacheTtl,\n // Handshake Protocol v10 enhanced fields (present when backend returns them)\n sessionId: (apiResponse as Record<string, unknown>).sessionId as string | undefined,\n // v2.3.10 (defect #34, round-4): anonymous responses surface correlationId\n // (no session row exists for unverified callers).\n correlationId: (apiResponse as Record<string, unknown>).correlationId as string | undefined,\n runtimeChallenge: (apiResponse as Record<string, unknown>).runtimeChallenge as\n | RuntimeChallengeResult\n | undefined,\n tokenGuidance: (apiResponse as Record<string, unknown>).tokenGuidance as\n | TokenGuidance\n | undefined,\n recommendation: (apiResponse as Record<string, unknown>)\n .recommendation as EnhancedVerificationResult['recommendation'],\n recommendationReasons: (apiResponse as Record<string, unknown>).recommendationReasons as\n | string[]\n | undefined,\n warningHeader: (apiResponse as Record<string, unknown>).warningHeader as\n | { name: string; value: string }\n | undefined,\n };\n\n // Enforce AstraSync recommendation\n if (result.recommendation === 'deny') {\n // Round-18 G4: recommendation-driven deny lands on the success-path\n // construction (identity was resolved). Flip policy only — identity stays\n // verified — so adapters return 403 (re-auth won't help; the policy\n // decision is the blocker).\n result.policyAllowed = false;\n result.accessLevel = 'none';\n result.denialReasons = result.recommendationReasons || [\n 'Access denied by AstraSync recommendation',\n ];\n if (result.runtimeChallenge) {\n result.guidance = {\n message: `Verification failed: ${result.runtimeChallenge.reason || 'runtime challenge failed'}`,\n registrationUrl: `${mergedConfig.apiBaseUrl?.replace('/api', '')}/register`,\n documentationUrl: `${mergedConfig.apiBaseUrl?.replace('/api', '')}/docs/runtime-challenge`,\n };\n }\n } else if (result.recommendation === 'step_up_required') {\n result.requiresStepUp = true;\n if (ACCESS_LEVEL_HIERARCHY[result.accessLevel] > ACCESS_LEVEL_HIERARCHY['read-only']) {\n result.accessLevel = 'read-only';\n }\n result.denialReasons = result.recommendationReasons || ['Step-up verification required'];\n }\n\n // Cache the result (skip caching denials — agent may fix challenge endpoint and retry)\n if (mergedConfig.cacheTtl && mergedConfig.cacheTtl > 0 && result.recommendation !== 'deny') {\n cacheResult(request.credentials, result, mergedConfig.cacheTtl);\n }\n\n return result;\n}\n\n/**\n * Record a counterparty's grant/deny decision for a verification session.\n * Fire-and-forget — errors are silently swallowed.\n */\n/**\n * v2.3.9 (defect #34): optional override metadata. Set when the SDK's\n * local enforcement (toolGate / methodGate / trustScore floor) rejected\n * a request the SERVER had granted. Backend emits a distinct\n * `verification.local_override` event so the activity feed surfaces the\n * divergence as a separate row.\n */\nexport interface DecisionOverride {\n overriddenBy: 'toolGate' | 'methodGate' | 'trustScore' | 'other';\n toolName?: string;\n requestedLevel?: AccessLevel;\n grantedLevel?: AccessLevel;\n}\n\nexport async function recordDecision(\n config: GatewayConfig,\n sessionId: string,\n decision: 'granted' | 'denied',\n reason?: string,\n override?: DecisionOverride\n): Promise<void> {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n headers['X-API-Key'] = config.apiKey;\n }\n\n await fetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n decision,\n reason,\n ...(override && {\n overriddenBy: override.overriddenBy,\n toolName: override.toolName,\n requestedLevel: override.requestedLevel,\n grantedLevel: override.grantedLevel,\n }),\n }),\n }).catch(() => {\n /* fire-and-forget */\n });\n}\n\n/**\n * v2.3.10 (defect #34, round-4): record a SDK-side local override for an\n * anonymous verify-access response. Anonymous traffic has no session row, so\n * `recordDecision` (above) doesn't apply — but we still need to surface the\n * dashboard-vs-runtime divergence (e.g. server granted with audit warning\n * but local toolGate floor denied) on the activity feed.\n *\n * Backend ties the resulting `verification.local_override` event back to the\n * original `verification.unverified_audit` event via `correlationId`. The\n * endpoint is sessionless — see the docstring on the backend route for the\n * abuse-mitigation rationale (rate-limited per IP).\n *\n * Fire-and-forget — errors are silently swallowed.\n */\nexport async function recordAnonymousLocalOverride(\n config: GatewayConfig,\n correlationId: string,\n override: DecisionOverride,\n reason?: string\n): Promise<void> {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n headers['X-API-Key'] = config.apiKey;\n }\n\n await fetch(`${config.apiBaseUrl}/agents/verify-access/local-override`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n correlationId,\n reason,\n overriddenBy: override.overriddenBy,\n toolName: override.toolName,\n requestedLevel: override.requestedLevel,\n grantedLevel: override.grantedLevel,\n }),\n }).catch(() => {\n /* fire-and-forget */\n });\n}\n\n/**\n * Fetch the per-route policy for an endpoint from the AstraSync backend.\n * v2.9.7 moved policy authority into the dashboard — the SDK no longer\n * accepts `routes` from merchant-side source code, it fetches them from\n * here on init (and refreshes periodically).\n *\n * Returns `null` when the request fails for any reason — the caller decides\n * how to fall back (the middleware allows-all when no policy is loaded so\n * a misconfigured init doesn't take down the merchant's API).\n */\nexport async function fetchRoutes(\n config: GatewayConfig,\n counterpartyId: string\n): Promise<RouteAccessConfigShape[] | null> {\n if (!counterpartyId) return null;\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n headers['X-API-Key'] = config.apiKey;\n }\n try {\n const response = await fetch(\n `${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes`,\n { method: 'GET', headers }\n );\n if (!response.ok) return null;\n const body = (await response.json()) as { data?: { routes?: RouteAccessConfigShape[] } };\n return body.data?.routes ?? [];\n } catch {\n return null;\n }\n}\n\n/**\n * Minimal shape of an EndpointRoute as the SDK consumes it. Mirrors the\n * server's `EndpointRoute` type and the SDK's `RouteAccessConfig` — same\n * JSON moves between server and SDK unchanged.\n */\nexport interface RouteAccessConfigShape {\n pattern: string;\n method: string;\n minAccessLevel: 'none' | 'restricted' | 'read-only' | 'standard' | 'full' | 'internal';\n minTrustScore?: number;\n requiredPurposes?: string[];\n allowedPurposes?: string[];\n allowedJurisdictions?: string[];\n maxDuration?: number;\n maxTransactionValue?: number;\n}\n\n/**\n * Verify an agent AND automatically record the grant/deny decision.\n *\n * This is the recommended entry point for counterparties that call verify()\n * directly (e.g. MCP servers) rather than using createMiddleware().\n * It adds createSession: true, then fire-and-forgets the decision.\n */\nexport async function verifyAndRecord(\n config: GatewayConfig,\n request: VerificationRequest\n): Promise<VerificationResult> {\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\n const result = await verify(mergedConfig, { ...request, createSession: true });\n const sessionId = (result as EnhancedVerificationResult).sessionId;\n\n if (sessionId) {\n // Round-18 G4: a session is \"granted\" only if identity verified AND\n // policy allowed; either failing is a deny.\n if (result.identityVerified && result.policyAllowed) {\n recordDecision(mergedConfig, sessionId, 'granted').catch(() => {});\n } else {\n recordDecision(mergedConfig, sessionId, 'denied', result.denialReasons?.[0]).catch(() => {});\n }\n }\n\n return result;\n}\n\n/**\n * Report an unregistered agent attempt (no AstraSync credentials).\n * Called by SDK adapters when an agent is redirected to /docs/agent-access.\n * Fire-and-forget — errors are silently swallowed.\n */\nexport async function reportUnregisteredAttempt(\n config: GatewayConfig,\n data: {\n counterpartyUrl: string;\n counterpartyType?: string;\n sourceIp?: string;\n userAgent?: string;\n requestPath?: string;\n requestMethod?: string;\n }\n): Promise<void> {\n const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl!;\n\n await fetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n }).catch(() => {\n /* fire-and-forget */\n });\n}\n\n/**\n * Report a counterparty-side PDLSS pre-check failure.\n * Called by SDK adapters when the agent's requested PDLSS exceeds\n * counterparty-defined maximums BEFORE calling verify-access.\n * Fire-and-forget — errors are silently swallowed.\n */\nexport async function reportCounterpartyPreCheckFailure(\n config: GatewayConfig,\n data: {\n agentId: string;\n counterpartyUrl: string;\n counterpartyType?: string;\n failures: Array<{\n field: string;\n requested: string | number;\n limit: string | number | string[];\n message: string;\n }>;\n requestPath?: string;\n requestMethod?: string;\n }\n): Promise<void> {\n const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl!;\n\n await fetch(`${apiBaseUrl}/verification-activity/counterparty-pre-check-failure`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n }).catch(() => {\n /* fire-and-forget */\n });\n}\n\n/**\n * Quick verification — checks credentials and policy in one call.\n *\n * Round-18 G4: return shape mirrors `VerificationResult`'s split — partners\n * writing custom handlers around `quickVerify` get the same identity/policy\n * distinction as those calling `verify()` directly. Map to HTTP status the\n * same way: `!identityVerified` → 401; `identityVerified && !policyAllowed`\n * → 403.\n */\nexport async function quickVerify(\n config: GatewayConfig,\n credentials: AgentCredentials\n): Promise<{\n identityVerified: boolean;\n policyAllowed: boolean;\n accessLevel: AccessLevel;\n reason?: string;\n}> {\n const result = await verify(config, {\n credentials,\n purpose: 'verification',\n });\n\n return {\n identityVerified: result.identityVerified,\n policyAllowed: result.policyAllowed,\n accessLevel: result.accessLevel,\n reason: result.denialReasons?.[0],\n };\n}\n","/**\n * AstraSync Universal Verification Gateway - Express Middleware\n *\n * Express.js middleware for verifying AI agents on API endpoints.\n *\n * @example\n * ```typescript\n * import express from 'express';\n * import { createMiddleware } from '@astrasyncai/verification-gateway/express';\n *\n * const app = express();\n *\n * app.use(createMiddleware({\n * apiBaseUrl: 'https://astrasync.ai/api',\n * routes: [\n * { pattern: '/api/public/*', method: '*', minAccessLevel: 'none' },\n * { pattern: '/api/data/*', method: 'GET', minAccessLevel: 'read-only' },\n * { pattern: '/api/data/*', method: '*', minAccessLevel: 'standard' },\n * { pattern: '/api/admin/*', method: '*', minAccessLevel: 'internal' },\n * ],\n * }));\n * ```\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type {\n ExpressMiddlewareOptions,\n AgentCredentials,\n VerificationResult,\n EnhancedVerificationResult,\n RouteAccessConfig,\n AstraSyncCredentials,\n} from '../types';\nimport {\n verify,\n extractCredentials,\n recordDecision,\n reportCounterpartyPreCheckFailure,\n fetchRoutes,\n} from '../verify';\nimport { hasMinimumAccess } from '../access-levels';\nimport { extractHttpCredentials } from '../transport/http';\nimport { performCounterpartyPreCheck } from '../pdlss-pre-check';\n\n/**\n * Extend Express Request with verification result\n */\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Express {\n interface Request {\n agentVerification?: VerificationResult;\n }\n }\n}\n\n/**\n * Default credential extractor\n */\nfunction defaultExtractCredentials(req: Request): AgentCredentials {\n return extractCredentials(\n req.headers as Record<string, string | string[] | undefined>,\n req.query as Record<string, string | undefined>\n );\n}\n\n/**\n * Extract extended AstraSync credentials (X-Astra-* headers) from Express request.\n * Returns null if no AstraSync headers are present.\n */\nexport function extractAstraSyncCredentials(req: Request): AstraSyncCredentials | null {\n return extractHttpCredentials(req.headers as Record<string, string | string[] | undefined>);\n}\n\n/**\n * Default purpose extractor.\n *\n * Priority:\n * 1. Agent's declared PDLSS purpose from X-Astra-Purpose header (e.g. \"read_data:search\")\n * 2. Explicit x-purpose header\n * 3. Query parameter ?purpose=\n * 4. HTTP method → PDLSS category fallback\n */\nfunction defaultExtractPurpose(req: Request): string | undefined {\n // 1. Check agent's declared PDLSS purpose (X-Astra-Purpose header)\n const astraPurpose = req.headers['x-astra-purpose'];\n if (astraPurpose) {\n const value = Array.isArray(astraPurpose) ? astraPurpose[0] : astraPurpose;\n // Extract category from \"category:action\" format — the verify API expects the category\n const category = value.split(':')[0];\n return category;\n }\n\n // 2. Try explicit purpose header\n const purposeHeader = req.headers['x-purpose'] || req.headers['X-Purpose'];\n if (purposeHeader) {\n return Array.isArray(purposeHeader) ? purposeHeader[0] : purposeHeader;\n }\n\n // 3. Try query parameter\n if (req.query.purpose && typeof req.query.purpose === 'string') {\n return req.query.purpose;\n }\n\n // 4. Infer from HTTP method using PDLSS-compatible categories\n switch (req.method) {\n case 'GET':\n return 'read_data';\n case 'POST':\n return 'write_data';\n case 'PUT':\n case 'PATCH':\n return 'write_data';\n case 'DELETE':\n return 'delete_data';\n default:\n return 'general';\n }\n}\n\n/**\n * Match a route pattern against a path\n */\nfunction matchRoute(pattern: string, path: string): boolean {\n // Convert pattern to regex\n const regexPattern = pattern.replace(/\\*/g, '.*').replace(/\\//g, '\\\\/');\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(path);\n}\n\n/**\n * Find the route configuration for a request\n */\nfunction findRouteConfig(\n routes: RouteAccessConfig[],\n path: string,\n method: string\n): RouteAccessConfig | undefined {\n return routes.find((route) => {\n const methodMatches =\n route.method === '*' || route.method.toUpperCase() === method.toUpperCase();\n const pathMatches = matchRoute(route.pattern, path);\n return methodMatches && pathMatches;\n });\n}\n\n/**\n * Default denied handler\n *\n * Round-10 (#47, O5): the response body now carries the full `failures[]`\n * array and the `correlationId` so partners can render per-dimension UX\n * and tie a denial back to a server log line. Previously the merchant only\n * got the first denialReason — meaningful detail was thrown away before\n * the response left the SDK. Also stamps `X-Astra-Gateway-Mode: enforced`\n * so partners can tell a gate-evaluated denial apart from a gate-skipped\n * pass-through (#49/O10 — the `unenforced` complement).\n */\nfunction defaultOnDenied(result: VerificationResult, _req: Request, res: Response): void {\n // Round-18 G4: identity-verification failures → 401 (re-authenticate);\n // identity-verified-but-policy-denied → 403 (re-auth won't help; update\n // PDLSS scope or escalate to step-up). Maps to the two distinct recovery\n // actions that HTTP middleware acts on without parsing bodies. The\n // impossible state `!identityVerified && policyAllowed` falls into the\n // `!identityVerified` branch — identity is the more-fundamental missing\n // precondition.\n const statusCode = !result.identityVerified ? 401 : 403;\n\n res.setHeader('X-Astra-Gateway-Mode', 'enforced');\n\n res.status(statusCode).json({\n success: false,\n error: {\n code: !result.identityVerified ? 'UNAUTHORIZED' : 'INSUFFICIENT_ACCESS',\n message: result.denialReasons?.[0] || 'Access denied',\n accessLevel: result.accessLevel,\n guidance: result.guidance,\n // Round-10: aggregated per-dimension detail + correlation handle.\n failures: result.failures,\n correlationId: result.correlationId,\n },\n });\n}\n\n/**\n * Refresh interval for the remote-fetched route policy. Default: every 5\n * minutes. Override via `routesRefreshMs` on the middleware options. Each\n * middleware instance keeps its own cache; multiple instances pointing at the\n * same endpoint will each fetch independently.\n */\nconst DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1000;\n\n/**\n * Create Express middleware for agent verification.\n *\n * v2.9.7 moved per-route policy authority out of merchant-side source code\n * into the AstraSync dashboard. `createMiddleware` no longer accepts a\n * `routes` array — it fetches the endpoint's stored policy via\n * `GET /endpoints/:counterpartyId/routes` on init and refreshes\n * periodically. Policy edits in the dashboard take effect on the next\n * refresh (or sooner if the operator manually restarts the SDK).\n *\n * `counterpartyId` is required: the SDK can't know which endpoint's policy\n * to fetch without it. Local-development workflows that don't have an\n * AstraSync endpoint registered can omit it — the middleware logs a\n * one-time warning and falls through (allows all) until a policy is\n * fetchable.\n */\nexport function createMiddleware(options: ExpressMiddlewareOptions): RequestHandler {\n const {\n extractCredentials: customExtractCredentials,\n extractPurpose: customExtractPurpose,\n skipPaths = [],\n onDenied = defaultOnDenied,\n recordDecisions,\n enableRuntimeChallenge = true,\n routesRefreshMs = DEFAULT_ROUTES_REFRESH_MS,\n ...config\n } = options;\n\n // Per-middleware-instance route cache. Populated on first fetch; refreshed\n // every `routesRefreshMs`. Until first successful fetch we hold an empty\n // array which means \"no per-route gating active\" — the middleware falls\n // through. Pre-fix the array came from merchant source, which both broke\n // the auth-boundary story (defect 24) and silently disagreed with the\n // dashboard.\n let cachedRoutes: RouteAccessConfig[] = [];\n let lastFetchAt = 0;\n let refreshing: Promise<void> | null = null;\n let warnedNoCounterparty = false;\n let warnedEmptyRoutes = false;\n\n async function refreshRoutes(): Promise<void> {\n if (!config.counterpartyId) {\n if (!warnedNoCounterparty) {\n // eslint-disable-next-line no-console\n console.warn(\n '[VerificationGateway] No counterpartyId configured — falling through (allow all). ' +\n 'Per-route policy lives in the AstraSync dashboard now; register the endpoint and ' +\n 'set counterpartyId in your middleware config to enforce policy.'\n );\n warnedNoCounterparty = true;\n }\n return;\n }\n const fetched = await fetchRoutes(config, config.counterpartyId);\n if (fetched) {\n cachedRoutes = fetched;\n lastFetchAt = Date.now();\n // v2.3.8 (defect #25): if the fetch succeeded but returned an empty\n // policy, the endpoint is registered correctly but the operator hasn't\n // configured any routes yet — every request will fall through ungated.\n // Surface this loudly once so silent pass-through can't go unnoticed.\n if (cachedRoutes.length === 0 && !warnedEmptyRoutes) {\n const dashboard = config.dashboardUrl ?? 'https://app.astrasync.ai';\n // eslint-disable-next-line no-console\n console.warn(\n `[VerificationGateway] No route policy configured for ${config.counterpartyId}. ` +\n `Gateway is in pass-through mode for ALL traffic until you add at least one route. ` +\n `Configure at ${dashboard}/dashboard/endpoints/${config.counterpartyId}/routes`\n );\n warnedEmptyRoutes = true;\n }\n }\n }\n\n // Eager first fetch so the first request after init has policy loaded.\n // Errors are swallowed (handled by fetchRoutes returning null).\n refreshing = refreshRoutes().finally(() => {\n refreshing = null;\n });\n\n return async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n // Check if path should be skipped\n const shouldSkip = skipPaths.some((pattern) => matchRoute(pattern, req.path));\n if (shouldSkip) {\n return next();\n }\n\n // Wait for in-flight init fetch (only on the very first request) so we\n // don't admit traffic with no policy loaded.\n if (refreshing) {\n await refreshing.catch(() => {});\n }\n // Time-based refresh: kick off a background refresh if the cache is\n // stale. Doesn't block the current request — readers see whatever is\n // cached at this moment; the next request will see the refreshed copy.\n if (config.counterpartyId && Date.now() - lastFetchAt > routesRefreshMs) {\n refreshing = refreshRoutes().finally(() => {\n refreshing = null;\n });\n }\n\n // Find route configuration\n const routeConfig = findRouteConfig(cachedRoutes, req.path, req.method);\n\n // If no route config, skip verification (allow through)\n if (!routeConfig) {\n if (config.setPassThroughHeader) {\n // Round-10 (#49, O10): `unenforced` replaces the previous\n // `pass-through` label. The previous name conflated \"gateway\n // didn't evaluate policy\" with \"request succeeded end-to-end\" —\n // the downstream handler may still return any status. The new\n // semantic describes the GATE state only.\n res.setHeader('X-Astra-Gateway-Mode', 'unenforced');\n res.setHeader(\n 'X-Astra-Gateway-Reason',\n cachedRoutes.length === 0 ? 'no-policy' : 'no-match'\n );\n }\n return next();\n }\n\n // Extract credentials (hoisted from below the route-none check so the\n // round-12 F9 evaluateAlwaysIfCredentialed flag can decide whether to\n // evaluate vs short-circuit).\n const credentials = customExtractCredentials\n ? customExtractCredentials(req)\n : defaultExtractCredentials(req);\n\n // Round-12 (F9): route-none short-circuit unless the caller wants\n // evaluation-without-enforcement. With evaluateAlwaysIfCredentialed\n // set to true AND credentials present, the middleware calls\n // verify-access for audit + req.agentVerification population, then\n // proceeds without gating. Default behaviour (flag off) preserves\n // pre-F9 short-circuit semantics.\n const shouldEnforce = routeConfig.minAccessLevel !== 'none';\n if (\n routeConfig.minAccessLevel === 'none' &&\n (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)\n ) {\n if (config.setPassThroughHeader) {\n res.setHeader('X-Astra-Gateway-Mode', 'unenforced');\n res.setHeader('X-Astra-Gateway-Reason', 'route-none');\n }\n return next();\n }\n\n // v2.3.0: anonymous traffic no longer short-circuits client-side.\n // The server applies the endpoint's `unverifiedAgentPolicy` (deny /\n // allow_partial / allow_full) and emits the verification event +\n // blockchain record per the canonical flow. SDK forwards verbatim.\n\n // Extract purpose\n const purpose = customExtractPurpose ? customExtractPurpose(req) : defaultExtractPurpose(req);\n\n // Extract full AstraSync credentials (includes PDLSS from X-Astra-* headers)\n const astraCreds = extractAstraSyncCredentials(req);\n\n // Auto-detect counterparty URL from the request if not explicitly configured.\n // Since the SDK is installed at this endpoint, we always know the origin.\n const counterpartyUrl = config.counterpartyUrl || `${req.protocol}://${req.get('host')}`;\n\n // Step 2: Counterparty-side PDLSS pre-check — compare agent's requested PDLSS\n // against counterparty-defined maximums on the route config.\n // Rejects immediately if outside limits, BEFORE calling verify-access.\n const preCheckFailures = performCounterpartyPreCheck(routeConfig, astraCreds, purpose);\n if (preCheckFailures.length > 0) {\n // Round-18 G4: counterparty pre-check failure — request rejected\n // before reaching verify-access. Neither identity nor policy was\n // remotely verified; both axes truthfully false.\n const result: VerificationResult = {\n identityVerified: false,\n policyAllowed: false,\n accessLevel: 'none',\n denialReasons: preCheckFailures.map((f) => f.message),\n guidance: {\n message: 'Request exceeds counterparty-defined PDLSS limits.',\n registrationUrl: `${config.apiBaseUrl?.replace('/api', '')}/register`,\n documentationUrl: `${config.apiBaseUrl?.replace('/api', '')}/docs/pdlss`,\n },\n verifiedAt: new Date(),\n };\n\n req.agentVerification = result;\n\n // Fire-and-forget: notify AstraSync of the pre-check failure\n reportCounterpartyPreCheckFailure(config, {\n agentId: astraCreds?.agentId || credentials.astraId || 'unknown',\n counterpartyUrl,\n counterpartyType: config.counterpartyType || 'api',\n failures: preCheckFailures,\n requestPath: req.path,\n requestMethod: req.method,\n }).catch(() => {});\n\n onDenied(result, req, res);\n return;\n }\n\n // Step 3: Call AstraSync verify-access with runtime challenge enabled\n const shouldRecordDecisions = recordDecisions !== false;\n const forwardedFor = req.headers['x-forwarded-for'];\n const forwardedForStr = Array.isArray(forwardedFor) ? forwardedFor.join(', ') : forwardedFor;\n // X-Forwarded-For's first entry is the original client. Fall back to req.ip\n // (which Express already resolves via trust proxy settings when configured).\n const originalClientIp = forwardedForStr ? forwardedForStr.split(',')[0].trim() : req.ip;\n const agentCardUrl =\n typeof req.headers['x-astrasync-agent-card'] === 'string'\n ? (req.headers['x-astrasync-agent-card'] as string)\n : undefined;\n\n const result = await verify(config, {\n credentials,\n purpose,\n action: req.method.toLowerCase(),\n resource: req.path,\n createSession: shouldRecordDecisions,\n counterpartyUrl,\n counterpartyType: config.counterpartyType || 'api',\n enableRuntimeChallenge,\n durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration,\n callerMetadata: {\n sourceIp: originalClientIp,\n userAgent: req.headers['user-agent'] as string | undefined,\n referer: req.headers.referer as string | undefined,\n host: req.headers.host as string | undefined,\n forwardedFor: forwardedForStr,\n agentCardUrl,\n },\n });\n\n // Attach result to request\n req.agentVerification = result;\n const sessionId = (result as EnhancedVerificationResult).sessionId;\n\n // v2.3.9 (defect #30): denied verifications short-circuit BEFORE the\n // gate-level comparison. Pre-rename, denials returned\n // `accessLevel: 'guidance'` and routes gated at `'guidance'` passed\n // `hasMinimumAccess('guidance', 'guidance') === true` — letting\n // unverified anonymous traffic through to the merchant handler. The\n // verify.ts denial branches now return `'none'` (so the gate check\n // alone would correctly deny), but trusting access-level math for a\n // denial is a category error: failing either identity OR policy already\n // means \"deny.\" We check that first.\n // Round-18 G4: short-circuit on either axis failing — identity-fail\n // (no resolved caller) or policy-fail (PDLSS or recommendation deny).\n if (!result.identityVerified || !result.policyAllowed) {\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'denied', result.denialReasons?.[0]).catch(() => {});\n }\n onDenied(result, req, res);\n return;\n }\n\n // Round-12 (F9): evaluation-without-enforcement. When the route is\n // 'none' but we ran verify-access for audit, skip the gates and call\n // next() — the result is on req.agentVerification for the handler\n // to render tier-aware responses (e.g. anonymous vs verified\n // catalog view on the same path).\n if (!shouldEnforce) {\n if (config.setPassThroughHeader) {\n res.setHeader('X-Astra-Gateway-Mode', 'enforced');\n res.setHeader('X-Astra-Gateway-Reason', 'evaluated-not-enforced');\n }\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'granted').catch(() => {});\n }\n return next();\n }\n\n // Check if access level is sufficient (verified caller path only —\n // denials handled above)\n if (!hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {\n // Round-12 (F12): synthesise the structured failure entry so the\n // partner-facing response carries the same shape as every other\n // denial dimension. Guidance positions step-up only — increasing\n // trust score or lowering the route floor both read as gaming the\n // gate. Step-up flow ships separately this month.\n const insufficientFailure = {\n dimension: 'access_level.insufficient',\n message: `Endpoint requires accessLevel '${routeConfig.minAccessLevel}'; agent has '${result.accessLevel}'.`,\n guidance:\n \"Request elevated access via step-up verification (coming soon — ships this month). Step-up lets the agent owner approve a one-time elevation for this specific counterparty + purpose without changing the agent's baseline trust score.\",\n };\n result.failures = [...(result.failures ?? []), insufficientFailure];\n result.denialReasons = [...(result.denialReasons ?? []), insufficientFailure.message];\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'denied', insufficientFailure.message).catch(() => {});\n }\n onDenied(result, req, res);\n return;\n }\n\n // Check trust score requirement if specified\n if (routeConfig.minTrustScore && result.agent) {\n if (result.agent.trustScore < routeConfig.minTrustScore) {\n // Round-12 (F12): structured failure entry + step-up framing.\n const trustFailure = {\n dimension: 'access_level.insufficient',\n message: `Trust score ${result.agent.trustScore} is below required ${routeConfig.minTrustScore} for this route.`,\n guidance:\n \"Request elevated access via step-up verification (coming soon — ships this month). Step-up lets the agent owner approve a one-time elevation for this specific counterparty + purpose without changing the agent's baseline trust score.\",\n };\n result.failures = [...(result.failures ?? []), trustFailure];\n result.denialReasons = [trustFailure.message];\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'denied', trustFailure.message).catch(() => {});\n }\n onDenied(result, req, res);\n return;\n }\n }\n\n // All checks passed — record grant decision\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'granted').catch(() => {});\n }\n // v2.3.8 (defect #26): if the endpoint's `unverifiedAgentPolicy` is\n // `'audit'` (allow + soft-launch warning), the server returns the\n // header to relay. Lift it onto the merchant's response BEFORE\n // calling next() so downstream handlers and the eventual response\n // back to the agent both carry it.\n const enhancedResult = result as EnhancedVerificationResult;\n if (enhancedResult.warningHeader) {\n res.setHeader(enhancedResult.warningHeader.name, enhancedResult.warningHeader.value);\n }\n next();\n } catch (error) {\n // Log error and continue (fail open by default)\n console.error('[VerificationGateway] Middleware error:', error);\n next();\n }\n };\n}\n\n// `requireAccess` and `verifyOnly` were removed in v2.9.7. Both injected a\n// local `routes` array into the merchant's source code, which is the exact\n// dual-config attack vector defect 24 closed. Per-route policy now lives in\n// the AstraSync dashboard (gated by team.role admin auth + audit + alerts).\n// To enforce a minimum tier, set the route's `minAccessLevel` in the\n// dashboard. For \"verify but don't block,\" set every route to `none` there.\n","/**\n * HTTP Transport Adapter\n *\n * Maps AstraSync credentials to/from HTTP headers (X-Astra-* convention).\n */\n\nimport type { AstraSyncCredentials } from '../types';\n\nconst HEADER_PREFIX = 'X-Astra-';\n\n/**\n * Inject AstraSync credentials into HTTP headers.\n */\nexport function setHttpHeaders(\n headers: Record<string, string>,\n credentials: AstraSyncCredentials,\n): Record<string, string> {\n const result = { ...headers };\n\n result[`${HEADER_PREFIX}ID`] = credentials.agentId;\n\n if (credentials.verifyUrl) {\n result[`${HEADER_PREFIX}Verify`] = credentials.verifyUrl;\n }\n\n if (credentials.challengeUrl) {\n result[`${HEADER_PREFIX}Challenge`] = credentials.challengeUrl;\n }\n\n if (credentials.pdlss?.purpose) {\n const purposeValue = credentials.pdlss.purpose.action\n ? `${credentials.pdlss.purpose.category}:${credentials.pdlss.purpose.action}`\n : credentials.pdlss.purpose.category;\n result[`${HEADER_PREFIX}Purpose`] = purposeValue;\n }\n\n if (credentials.pdlss?.duration?.maxSessionDuration) {\n result[`${HEADER_PREFIX}Duration`] = String(credentials.pdlss.duration.maxSessionDuration);\n }\n\n if (credentials.pdlss?.scope?.jurisdiction) {\n result[`${HEADER_PREFIX}Scope`] = credentials.pdlss.scope.jurisdiction;\n }\n\n return result;\n}\n\n/**\n * Extract AstraSync credentials from HTTP headers.\n */\nexport function extractHttpCredentials(\n headers: Record<string, string | string[] | undefined>,\n): AstraSyncCredentials | null {\n const getValue = (key: string): string | undefined => {\n const v = headers[key] ?? headers[key.toLowerCase()];\n return Array.isArray(v) ? v[0] : v;\n };\n\n const agentId = getValue(`${HEADER_PREFIX}ID`) ?? getValue('x-astra-id');\n if (!agentId) return null;\n\n const credentials: AstraSyncCredentials = { agentId };\n\n const verifyUrl = getValue(`${HEADER_PREFIX}Verify`) ?? getValue('x-astra-verify');\n if (verifyUrl) credentials.verifyUrl = verifyUrl;\n\n const challengeUrl = getValue(`${HEADER_PREFIX}Challenge`) ?? getValue('x-astra-challenge');\n if (challengeUrl) credentials.challengeUrl = challengeUrl;\n\n const purpose = getValue(`${HEADER_PREFIX}Purpose`) ?? getValue('x-astra-purpose');\n if (purpose) {\n const [category, action] = purpose.split(':');\n credentials.pdlss = {\n ...credentials.pdlss,\n purpose: { category, action },\n };\n }\n\n const duration = getValue(`${HEADER_PREFIX}Duration`) ?? getValue('x-astra-duration');\n if (duration) {\n credentials.pdlss = {\n ...credentials.pdlss,\n duration: { maxSessionDuration: parseInt(duration, 10) },\n };\n }\n\n const scope = getValue(`${HEADER_PREFIX}Scope`) ?? getValue('x-astra-scope');\n if (scope) {\n credentials.pdlss = {\n ...credentials.pdlss,\n scope: { jurisdiction: scope },\n };\n }\n\n return credentials;\n}\n","/**\n * Counterparty-side PDLSS pre-check.\n *\n * Compares the agent's requested PDLSS dimensions (from X-Astra-* headers)\n * against the counterparty-defined maximums on the route config.\n * Returns an array of failures — empty means all checks passed.\n *\n * This runs BEFORE calling verify-access on AstraSync. If it fails,\n * the request is rejected immediately without calling the platform.\n */\n\nimport type { RouteAccessConfig, AstraSyncCredentials, CounterpartyPreCheckFailure } from './types';\n\nexport function performCounterpartyPreCheck(\n routeConfig: RouteAccessConfig,\n astraCreds: AstraSyncCredentials | null,\n purpose: string | undefined,\n): CounterpartyPreCheckFailure[] {\n const failures: CounterpartyPreCheckFailure[] = [];\n\n // Check purpose against allowedPurposes whitelist\n if (routeConfig.allowedPurposes && routeConfig.allowedPurposes.length > 0 && purpose) {\n if (!routeConfig.allowedPurposes.includes(purpose)) {\n failures.push({\n field: 'purpose',\n requested: purpose,\n limit: routeConfig.allowedPurposes,\n message: `Purpose \"${purpose}\" is not in the allowed list: [${routeConfig.allowedPurposes.join(', ')}]`,\n });\n }\n }\n\n // Check purpose against requiredPurposes (legacy field — agent must declare one of these)\n if (routeConfig.requiredPurposes && routeConfig.requiredPurposes.length > 0 && purpose) {\n if (!routeConfig.requiredPurposes.includes(purpose)) {\n failures.push({\n field: 'purpose',\n requested: purpose,\n limit: routeConfig.requiredPurposes,\n message: `Purpose \"${purpose}\" is not in the required list: [${routeConfig.requiredPurposes.join(', ')}]`,\n });\n }\n }\n\n // Check duration against maxDuration\n if (routeConfig.maxDuration && astraCreds?.pdlss?.duration?.maxSessionDuration) {\n const requested = astraCreds.pdlss.duration.maxSessionDuration;\n if (requested > routeConfig.maxDuration) {\n failures.push({\n field: 'duration',\n requested,\n limit: routeConfig.maxDuration,\n message: `Requested duration ${requested}s exceeds maximum ${routeConfig.maxDuration}s`,\n });\n }\n }\n\n // Check jurisdiction against allowedJurisdictions\n if (\n routeConfig.allowedJurisdictions &&\n routeConfig.allowedJurisdictions.length > 0 &&\n astraCreds?.pdlss?.scope?.jurisdiction\n ) {\n const requested = astraCreds.pdlss.scope.jurisdiction;\n if (!routeConfig.allowedJurisdictions.includes(requested)) {\n failures.push({\n field: 'jurisdiction',\n requested,\n limit: routeConfig.allowedJurisdictions,\n message: `Jurisdiction \"${requested}\" is not in the allowed list: [${routeConfig.allowedJurisdictions.join(', ')}]`,\n });\n }\n }\n\n return failures;\n}\n","/**\n * AstraSync Universal Verification Gateway - Next.js Middleware\n *\n * Next.js middleware for verifying AI agents on web applications.\n * Supports Commerce Shield overlay for unverified agents.\n *\n * @example\n * ```typescript\n * // middleware.ts\n * import { createMiddleware } from '@astrasyncai/verification-gateway/nextjs';\n *\n * export const middleware = createMiddleware({\n * apiBaseUrl: 'https://api.astrasync.ai',\n * showCommerceShield: true,\n * routes: [\n * { pattern: '/api/public/*', method: '*', minAccessLevel: 'none' },\n * { pattern: '/api/*', method: '*', minAccessLevel: 'standard' },\n * { pattern: '/dashboard/*', method: '*', minAccessLevel: 'read-only' },\n * ],\n * });\n *\n * export const config = {\n * matcher: ['/api/:path*', '/dashboard/:path*'],\n * };\n * ```\n */\n\nimport type { NextRequest } from 'next/server';\nimport type {\n NextJsMiddlewareOptions,\n AgentCredentials,\n VerificationResult,\n RouteAccessConfig,\n AstraSyncCredentials,\n} from '../types';\nimport { verify, reportCounterpartyPreCheckFailure, fetchRoutes } from '../verify';\nimport { hasMinimumAccess } from '../access-levels';\nimport { extractHttpCredentials } from '../transport/http';\nimport { performCounterpartyPreCheck } from '../pdlss-pre-check';\n\n/**\n * Extract credentials from Next.js request\n */\nfunction extractCredentialsFromNextRequest(request: NextRequest): AgentCredentials {\n const credentials: AgentCredentials = {};\n\n // Check for ASTRA-ID in headers\n const astraId = request.headers.get('x-astra-id') || request.headers.get('X-Astra-Id');\n if (astraId) {\n credentials.astraId = astraId;\n }\n\n // Check for API key\n const apiKey = request.headers.get('x-api-key') || request.headers.get('X-Api-Key');\n if (apiKey) {\n credentials.apiKey = apiKey;\n }\n\n // Check Authorization header\n const authHeader = request.headers.get('authorization');\n if (authHeader) {\n credentials.authorizationHeader = authHeader;\n if (authHeader.startsWith('Bearer ')) {\n credentials.jwt = authHeader.slice(7);\n }\n }\n\n // Check query parameters\n const url = new URL(request.url);\n const astraIdParam = url.searchParams.get('astraId');\n const apiKeyParam = url.searchParams.get('apiKey');\n\n if (astraIdParam && !credentials.astraId) {\n credentials.astraId = astraIdParam;\n }\n if (apiKeyParam && !credentials.apiKey) {\n credentials.apiKey = apiKeyParam;\n }\n\n return credentials;\n}\n\n/**\n * Match a route pattern against a path\n */\nfunction matchRoute(pattern: string, path: string): boolean {\n const regexPattern = pattern.replace(/\\*/g, '.*').replace(/\\//g, '\\\\/');\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(path);\n}\n\n/**\n * Find the route configuration for a request\n */\nfunction findRouteConfig(\n routes: RouteAccessConfig[],\n path: string,\n method: string\n): RouteAccessConfig | undefined {\n return routes.find((route) => {\n const methodMatches =\n route.method === '*' || route.method.toUpperCase() === method.toUpperCase();\n const pathMatches = matchRoute(route.pattern, path);\n return methodMatches && pathMatches;\n });\n}\n\n/**\n * Extract AstraSyncCredentials from Next.js request headers.\n * Returns null if no AstraSync headers are present.\n */\nfunction extractAstraSyncCredentialsFromNextRequest(\n request: NextRequest\n): AstraSyncCredentials | null {\n const headers: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n headers[key] = value;\n });\n return extractHttpCredentials(headers);\n}\n\n/**\n * Extract purpose from request.\n *\n * Priority:\n * 1. Agent's declared PDLSS purpose from X-Astra-Purpose header (e.g. \"read_data:search\")\n * 2. Explicit x-purpose header\n * 3. HTTP method → PDLSS category fallback\n */\nfunction extractPurpose(request: NextRequest): string {\n // 1. Check agent's declared PDLSS purpose (X-Astra-Purpose header)\n const astraPurpose = request.headers.get('x-astra-purpose');\n if (astraPurpose) {\n // Extract category from \"category:action\" format\n return astraPurpose.split(':')[0];\n }\n\n // 2. Try explicit purpose header\n const purposeHeader = request.headers.get('x-purpose');\n if (purposeHeader) {\n return purposeHeader;\n }\n\n // 3. Infer from HTTP method using PDLSS-compatible categories\n switch (request.method.toUpperCase()) {\n case 'GET':\n return 'read_data';\n case 'POST':\n return 'write_data';\n case 'PUT':\n case 'PATCH':\n return 'write_data';\n case 'DELETE':\n return 'delete_data';\n default:\n return 'general';\n }\n}\n\n/**\n * Generate Commerce Shield HTML response\n */\nfunction generateCommerceShieldHtml(\n result: VerificationResult,\n options: NextJsMiddlewareOptions\n): string {\n const title = options.commerceShield?.title || 'AstraSync Agent Verification';\n const message =\n options.commerceShield?.message ||\n result.guidance?.message ||\n \"This site verifies AI agents before granting access. We noticed you're visiting without AstraSync credentials.\";\n const registrationUrl = result.guidance?.registrationUrl || 'https://astrasync.ai/register';\n const docsUrl = result.guidance?.documentationUrl || 'https://astrasync.ai/docs/agent-access';\n const allowGuest = options.commerceShield?.allowGuestAccess ?? true;\n\n return `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${title}</title>\n <style>\n * {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n }\n .shield-container {\n background: rgba(255, 255, 255, 0.95);\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);\n max-width: 480px;\n width: 100%;\n padding: 40px;\n text-align: center;\n }\n .shield-icon {\n font-size: 48px;\n margin-bottom: 20px;\n }\n .shield-title {\n font-size: 24px;\n font-weight: 700;\n color: #1a1a2e;\n margin-bottom: 16px;\n }\n .shield-message {\n color: #4a5568;\n line-height: 1.6;\n margin-bottom: 24px;\n }\n .shield-steps {\n text-align: left;\n background: #f7fafc;\n border-radius: 8px;\n padding: 20px;\n margin-bottom: 24px;\n }\n .shield-steps h3 {\n font-size: 14px;\n font-weight: 600;\n color: #2d3748;\n margin-bottom: 12px;\n }\n .shield-steps ol {\n padding-left: 20px;\n color: #4a5568;\n }\n .shield-steps li {\n margin-bottom: 8px;\n }\n .shield-buttons {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .btn {\n display: inline-block;\n padding: 14px 24px;\n border-radius: 8px;\n font-weight: 600;\n text-decoration: none;\n transition: all 0.2s;\n cursor: pointer;\n border: none;\n font-size: 16px;\n }\n .btn-primary {\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n color: white;\n }\n .btn-primary:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);\n }\n .btn-secondary {\n background: #e2e8f0;\n color: #4a5568;\n }\n .btn-secondary:hover {\n background: #cbd5e0;\n }\n .shield-footer {\n margin-top: 24px;\n font-size: 14px;\n color: #718096;\n }\n .shield-footer a {\n color: #6366f1;\n text-decoration: none;\n }\n .shield-footer a:hover {\n text-decoration: underline;\n }\n </style>\n</head>\n<body>\n <div class=\"shield-container\">\n <div class=\"shield-icon\">🛡️</div>\n <h1 class=\"shield-title\">${title}</h1>\n <p class=\"shield-message\">${message}</p>\n\n <div class=\"shield-steps\">\n <h3>To get verified access:</h3>\n <ol>\n <li>Register at <a href=\"${registrationUrl}\">astrasync.ai/register</a></li>\n <li>Create and register your agent</li>\n <li>Add your ASTRA-ID to request headers</li>\n <li>Refresh this page</li>\n </ol>\n </div>\n\n <div class=\"shield-buttons\">\n <a href=\"${registrationUrl}\" class=\"btn btn-primary\">Register Now</a>\n ${allowGuest ? '<button onclick=\"window.location.reload()\" class=\"btn btn-secondary\">Continue as Guest (Limited)</button>' : ''}\n </div>\n\n <p class=\"shield-footer\">\n Learn more: <a href=\"${docsUrl}\">Agent Access Documentation</a>\n </p>\n </div>\n</body>\n</html>\n `.trim();\n}\n\nconst DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1000;\n\n/**\n * Create Next.js middleware for agent verification.\n *\n * v2.9.7 moved per-route policy out of merchant-side source code into the\n * AstraSync dashboard. The middleware fetches its routes from the backend\n * via `GET /endpoints/:counterpartyId/routes` on init and refreshes\n * periodically — see `ExpressMiddlewareOptions` for the rationale (defect\n * 24, dual-config silent-conflict).\n */\nexport function createMiddleware(options: NextJsMiddlewareOptions) {\n const {\n skipPaths = [],\n showCommerceShield = true,\n enableRuntimeChallenge = true,\n routesRefreshMs = DEFAULT_ROUTES_REFRESH_MS,\n ...config\n } = options;\n\n let cachedRoutes: RouteAccessConfig[] = [];\n let lastFetchAt = 0;\n let refreshing: Promise<void> | null = null;\n let warnedNoCounterparty = false;\n\n async function refreshRoutes(): Promise<void> {\n if (!config.counterpartyId) {\n if (!warnedNoCounterparty) {\n // eslint-disable-next-line no-console\n console.warn(\n '[VerificationGateway/Next.js] No counterpartyId configured — falling through (allow all). ' +\n 'Per-route policy lives in the AstraSync dashboard now; register the endpoint and ' +\n 'set counterpartyId in your middleware config to enforce policy.'\n );\n warnedNoCounterparty = true;\n }\n return;\n }\n const fetched = await fetchRoutes(config, config.counterpartyId);\n if (fetched) {\n cachedRoutes = fetched;\n lastFetchAt = Date.now();\n }\n }\n\n refreshing = refreshRoutes().finally(() => {\n refreshing = null;\n });\n\n return async function middleware(request: NextRequest) {\n // Dynamic import NextResponse to avoid build issues\n const { NextResponse } = await import('next/server');\n\n const pathname = request.nextUrl.pathname;\n\n // Check if path should be skipped\n const shouldSkip = skipPaths.some((pattern) => matchRoute(pattern, pathname));\n if (shouldSkip) {\n return NextResponse.next();\n }\n\n if (refreshing) {\n await refreshing.catch(() => {});\n }\n if (config.counterpartyId && Date.now() - lastFetchAt > routesRefreshMs) {\n refreshing = refreshRoutes().finally(() => {\n refreshing = null;\n });\n }\n\n // Find route configuration (from remote-fetched cache)\n const routeConfig = findRouteConfig(cachedRoutes, pathname, request.method);\n\n // If no route config, allow through\n if (!routeConfig) {\n return NextResponse.next();\n }\n\n // If route requires 'none' access, allow through\n if (routeConfig.minAccessLevel === 'none') {\n return NextResponse.next();\n }\n\n // Extract credentials\n const credentials = extractCredentialsFromNextRequest(request);\n\n // v2.3.0: anonymous traffic no longer short-circuits client-side.\n // The server applies the endpoint's `unverifiedAgentPolicy` (deny /\n // allow_partial / allow_full) and emits the verification event +\n // blockchain record per the canonical flow. SDK forwards verbatim.\n\n // Auto-detect counterparty URL from the request if not explicitly configured.\n // Since the SDK is installed at this endpoint, we always know the origin.\n const counterpartyUrl = config.counterpartyUrl || request.nextUrl.origin;\n\n // Extract purpose and full AstraSync credentials (includes PDLSS from X-Astra-* headers)\n const purpose = extractPurpose(request);\n const astraCreds = extractAstraSyncCredentialsFromNextRequest(request);\n\n // Step 2: Counterparty-side PDLSS pre-check — compare agent's requested PDLSS\n // against counterparty-defined maximums on the route config.\n // Rejects immediately if outside limits, BEFORE calling verify-access.\n const preCheckFailures = performCounterpartyPreCheck(routeConfig, astraCreds, purpose);\n if (preCheckFailures.length > 0) {\n // Round-18 G4: counterparty pre-check failure — see express.ts for the\n // rationale. Neither axis verified remotely → both false.\n const preCheckResult: VerificationResult = {\n identityVerified: false,\n policyAllowed: false,\n accessLevel: 'none',\n denialReasons: preCheckFailures.map((f) => f.message),\n guidance: {\n message: 'Request exceeds counterparty-defined PDLSS limits.',\n registrationUrl: `${config.apiBaseUrl?.replace('/api', '')}/register`,\n documentationUrl: `${config.apiBaseUrl?.replace('/api', '')}/docs/pdlss`,\n },\n verifiedAt: new Date(),\n };\n\n // Fire-and-forget: notify AstraSync of the pre-check failure\n reportCounterpartyPreCheckFailure(config, {\n agentId: astraCreds?.agentId || credentials.astraId || 'unknown',\n counterpartyUrl,\n counterpartyType: config.counterpartyType || 'website',\n failures: preCheckFailures,\n requestPath: pathname,\n requestMethod: request.method,\n }).catch(() => {});\n\n // For API routes, return JSON\n if (pathname.startsWith('/api/')) {\n return NextResponse.json(\n {\n success: false,\n error: {\n code: 'PDLSS_PRE_CHECK_FAILED',\n message: preCheckResult.denialReasons?.[0] || 'PDLSS pre-check failed',\n guidance: preCheckResult.guidance,\n },\n },\n { status: 403 }\n );\n }\n\n // For web pages, show Commerce Shield\n if (showCommerceShield) {\n return new NextResponse(generateCommerceShieldHtml(preCheckResult, options), {\n status: 200,\n headers: {\n 'Content-Type': 'text/html',\n 'X-AstraSync-Verification': 'commerce-shield',\n },\n });\n }\n\n return NextResponse.redirect(new URL('/unauthorized', request.url));\n }\n\n // Step 3: Call AstraSync verify-access with runtime challenge enabled\n const forwardedFor = request.headers.get('x-forwarded-for') || undefined;\n const originalClientIp = forwardedFor?.split(',')[0]?.trim();\n const result = await verify(config, {\n credentials,\n purpose,\n action: request.method.toLowerCase(),\n resource: pathname,\n counterpartyUrl,\n counterpartyType: config.counterpartyType || 'website',\n enableRuntimeChallenge,\n durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration,\n callerMetadata: {\n sourceIp: originalClientIp,\n userAgent: request.headers.get('user-agent') || undefined,\n referer: request.headers.get('referer') || undefined,\n host: request.headers.get('host') || undefined,\n forwardedFor,\n agentCardUrl: request.headers.get('x-astrasync-agent-card') || undefined,\n },\n });\n\n // v2.3.9 (defect #30): denied verifications short-circuit BEFORE the\n // gate-level comparison. The OR-prefix shape here keeps the\n // single-expression branch this adapter uses, but ensures any axis of\n // failure triggers the denial path even if the access level math would\n // otherwise let it through (the historical bug). See express.ts for the\n // full rationale.\n // Round-18 G4: short-circuit on either axis failing (identity-fail or\n // policy-fail). The OR with hasMinimumAccess() preserves access-level\n // gating for over-tier requests.\n if (\n !result.identityVerified ||\n !result.policyAllowed ||\n !hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)\n ) {\n // For API routes, return JSON\n if (pathname.startsWith('/api/')) {\n return NextResponse.json(\n {\n success: false,\n error: {\n // Round-18 G4: 401 → identity missing (re-auth); 403 → identity\n // OK, policy denied (update PDLSS / step up).\n code: !result.identityVerified ? 'UNAUTHORIZED' : 'INSUFFICIENT_ACCESS',\n message: result.denialReasons?.[0] || 'Access denied',\n accessLevel: result.accessLevel,\n required: routeConfig.minAccessLevel,\n guidance: result.guidance,\n },\n },\n { status: !result.identityVerified ? 401 : 403 }\n );\n }\n\n // For web pages, show Commerce Shield\n if (showCommerceShield) {\n return new NextResponse(generateCommerceShieldHtml(result, options), {\n status: 200,\n headers: {\n 'Content-Type': 'text/html',\n 'X-AstraSync-Verification': 'commerce-shield',\n },\n });\n }\n\n // Redirect to unauthorized page\n return NextResponse.redirect(new URL('/unauthorized', request.url));\n }\n\n // All checks passed - continue with verification info in headers\n const response = NextResponse.next();\n\n // Add verification info to response headers\n // Round-18 G4: composite `verified` (identity AND policy) for legacy\n // header consumers; new headers expose each axis separately so middleware\n // chains can branch without re-running verify-access.\n response.headers.set(\n 'X-AstraSync-Verified',\n (result.identityVerified && result.policyAllowed).toString()\n );\n response.headers.set('X-AstraSync-Identity-Verified', result.identityVerified.toString());\n response.headers.set('X-AstraSync-Policy-Allowed', result.policyAllowed.toString());\n response.headers.set('X-AstraSync-Access-Level', result.accessLevel);\n\n if (result.agent) {\n response.headers.set('X-AstraSync-Agent-Id', result.agent.astraId);\n response.headers.set('X-AstraSync-Trust-Score', result.agent.trustScore.toString());\n }\n\n return response;\n };\n}\n\n/**\n * Helper to create matcher config\n */\nexport function createMatcherConfig(paths: string[]): { matcher: string[] } {\n return { matcher: paths };\n}\n","/**\n * AstraSync Universal Verification Gateway - SDK Adapter\n *\n * Direct SDK for verifying agents in any JavaScript/TypeScript environment.\n * Useful for agent-to-agent verification, serverless functions, or custom integrations.\n *\n * @example\n * ```typescript\n * import { createClient } from '@astrasyncai/verification-gateway/sdk';\n *\n * const gateway = createClient({\n * apiBaseUrl: 'https://astrasync.ai/api',\n * });\n *\n * // Verify another agent before interacting\n * const result = await gateway.verify({\n * astraId: 'ASTRA-abc123',\n * purpose: 'data-exchange',\n * });\n *\n * if (result.identityVerified && result.policyAllowed && result.accessLevel !== 'none') {\n * // Safe to interact with this agent\n * }\n * ```\n */\n\nimport type {\n SDKOptions,\n AgentCredentials,\n VerificationResult,\n VerificationRequest,\n AccessLevel,\n GatewayConfig,\n} from '../types';\nimport { verify as coreVerify, quickVerify as coreQuickVerify, clearCache } from '../verify';\nimport { getTrustLevel, hasMinimumAccess, getCapabilities } from '../access-levels';\nimport type { AccessCapabilities } from '../access-levels';\n\n/**\n * Verification Gateway SDK Client\n */\nexport class VerificationGatewayClient {\n private config: GatewayConfig;\n private timeout: number;\n private retryConfig: { maxRetries: number; backoffMs: number };\n\n constructor(options: SDKOptions) {\n this.config = {\n apiBaseUrl: options.apiBaseUrl,\n apiKey: options.apiKey,\n defaultAccessLevel: options.defaultAccessLevel,\n minTrustScore: options.minTrustScore,\n minTrustScoreForFull: options.minTrustScoreForFull,\n cacheTtl: options.cacheTtl,\n debug: options.debug,\n customHeaders: options.customHeaders,\n counterpartyUrl: options.counterpartyUrl,\n counterpartyType: options.counterpartyType,\n };\n\n this.timeout = options.timeout || 10000;\n this.retryConfig = options.retry || { maxRetries: 3, backoffMs: 1000 };\n }\n\n /**\n * Full verification with all details\n */\n async verify(options: {\n astraId?: string;\n apiKey?: string;\n jwt?: string;\n purpose?: string;\n action?: string;\n resourceType?: string;\n resource?: string;\n jurisdiction?: string;\n transactionValue?: number;\n currency?: string;\n isSubAgentRequest?: boolean;\n parentAgentId?: string;\n subAgentDepth?: number;\n counterpartyUrl?: string;\n counterpartyType?: string;\n }): Promise<VerificationResult> {\n const credentials: AgentCredentials = {\n astraId: options.astraId,\n apiKey: options.apiKey,\n jwt: options.jwt,\n };\n\n return this.executeWithRetry(() =>\n coreVerify(this.config, {\n credentials,\n purpose: options.purpose,\n action: options.action,\n resourceType: options.resourceType,\n resource: options.resource,\n jurisdiction: options.jurisdiction,\n transactionValue: options.transactionValue,\n currency: options.currency,\n isSubAgentRequest: options.isSubAgentRequest,\n parentAgentId: options.parentAgentId,\n subAgentDepth: options.subAgentDepth,\n counterpartyUrl: options.counterpartyUrl,\n counterpartyType: options.counterpartyType as VerificationRequest['counterpartyType'],\n })\n );\n }\n\n /**\n * Quick verification — checks credentials and policy in one call.\n *\n * Round-18 G4: return shape mirrors `VerificationResult`'s identity/policy\n * split. Map to HTTP status the same way: `!identityVerified` → 401,\n * `identityVerified && !policyAllowed` → 403.\n */\n async quickVerify(credentials: { astraId?: string; apiKey?: string; jwt?: string }): Promise<{\n identityVerified: boolean;\n policyAllowed: boolean;\n accessLevel: AccessLevel;\n reason?: string;\n }> {\n return this.executeWithRetry(() => coreQuickVerify(this.config, credentials));\n }\n\n /**\n * Check if an agent has a specific access level\n */\n async hasAccess(\n credentials: { astraId?: string; apiKey?: string; jwt?: string },\n requiredLevel: AccessLevel\n ): Promise<boolean> {\n const result = await this.quickVerify(credentials);\n return hasMinimumAccess(result.accessLevel, requiredLevel);\n }\n\n /**\n * Get capabilities for a verified agent\n */\n async getCapabilities(credentials: {\n astraId?: string;\n apiKey?: string;\n jwt?: string;\n }): Promise<AccessCapabilities> {\n const result = await this.quickVerify(credentials);\n return getCapabilities(result.accessLevel);\n }\n\n /**\n * Verify a specific ASTRA-ID\n */\n async verifyAstraId(\n astraId: string,\n options?: {\n purpose?: string;\n action?: string;\n }\n ): Promise<VerificationResult> {\n return this.verify({\n astraId,\n purpose: options?.purpose,\n action: options?.action,\n });\n }\n\n /**\n * Verify using an API key\n */\n async verifyApiKey(\n apiKey: string,\n options?: {\n purpose?: string;\n action?: string;\n }\n ): Promise<VerificationResult> {\n return this.verify({\n apiKey,\n purpose: options?.purpose,\n action: options?.action,\n });\n }\n\n /**\n * Clear the verification cache\n */\n clearCache(): void {\n clearCache();\n }\n\n /**\n * Execute a function with retry logic\n */\n private async executeWithRetry<T>(fn: () => Promise<T>): Promise<T> {\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {\n try {\n // Add timeout\n const result = await Promise.race([\n fn(),\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('Request timeout')), this.timeout)\n ),\n ]);\n\n return result;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't retry on last attempt\n if (attempt < this.retryConfig.maxRetries) {\n // Exponential backoff\n const backoff = this.retryConfig.backoffMs * Math.pow(2, attempt);\n await new Promise((resolve) => setTimeout(resolve, backoff));\n }\n }\n }\n\n throw lastError || new Error('Verification failed after retries');\n }\n}\n\n/**\n * Create a new SDK client\n */\nexport function createClient(options: SDKOptions): VerificationGatewayClient {\n return new VerificationGatewayClient(options);\n}\n\n/**\n * One-shot verification without creating a client\n */\nexport async function verifyOnce(\n options: SDKOptions & {\n astraId?: string;\n apiKey?: string;\n jwt?: string;\n purpose?: string;\n action?: string;\n }\n): Promise<VerificationResult> {\n const client = createClient(options);\n return client.verify(options);\n}\n\n// Re-export utilities for convenience\nexport { getTrustLevel, hasMinimumAccess, getCapabilities };\n","/**\n * Cross-Protocol Transport Module\n *\n * Provides adapters for injecting/extracting AstraSync credentials\n * across HTTP, A2A, and MCP protocols.\n */\n\nimport type { AstraSyncCredentials, ProtocolTransport } from '../types';\nimport { setHttpHeaders, extractHttpCredentials } from './http';\nimport { setA2AMetadata, extractA2ACredentials } from './a2a';\nimport { setMcpMeta, extractMcpCredentials } from './mcp';\n\nexport { setHttpHeaders, extractHttpCredentials } from './http';\nexport { setA2AMetadata, extractA2ACredentials } from './a2a';\nexport { setMcpMeta, extractMcpCredentials } from './mcp';\n\n// Commerce protocol extractors + verifiers (PR 4+5)\nexport * from './purpose-mapping';\nexport * from './transaction-value';\nexport * from './rfc9421';\nexport * from './rfc9421-verify';\nexport * from './ucp';\nexport * from './acp';\nexport * from './vi';\nexport * from './stripe-webhook';\nexport * from './constraint-eval';\nexport * from './identity-binding';\nexport * from './ap2';\nexport * from './ap2-verify';\nexport * from './acp-verify';\nexport * from './mpp';\nexport * from './mpp-verify';\nexport * from './x402';\nexport * from './vi-verify';\nexport * from './commerce-pipeline';\nexport * from './extractor-registry';\nexport * from './registry/types';\nexport { createVisaRegistry } from './registry/visa';\nexport { createMastercardRegistry } from './registry/mastercard';\nexport { createWebBotAuthRegistry } from './registry/web-bot-auth';\n\n/**\n * Auto-detect protocol from request/context shape.\n */\nexport function detectProtocol(context: Record<string, unknown>): ProtocolTransport {\n // A2A: has metadata block with task-like structure\n if (context.metadata && typeof context.metadata === 'object') {\n return 'a2a';\n }\n\n // MCP: has _meta block (MCP convention)\n if (context._meta && typeof context._meta === 'object') {\n return 'mcp';\n }\n\n // Default to HTTP\n return 'http';\n}\n\n/**\n * Apply credentials to any protocol target.\n */\nexport function applyCredentials(\n protocol: ProtocolTransport,\n target: Record<string, unknown>,\n credentials: AstraSyncCredentials\n): Record<string, unknown> {\n switch (protocol) {\n case 'http':\n return setHttpHeaders(target as Record<string, string>, credentials);\n case 'a2a':\n return setA2AMetadata(target, credentials);\n case 'mcp':\n return setMcpMeta(target, credentials);\n default:\n return target;\n }\n}\n\n/**\n * Extract credentials from any protocol context.\n */\nexport function extractCredentialsFromProtocol(\n protocol: ProtocolTransport,\n context: Record<string, unknown>\n): AstraSyncCredentials | null {\n switch (protocol) {\n case 'http':\n return extractHttpCredentials(context as Record<string, string | string[] | undefined>);\n case 'a2a':\n return extractA2ACredentials(context);\n case 'mcp':\n return extractMcpCredentials(context);\n default:\n return null;\n }\n}\n","/**\n * A2A (Agent-to-Agent) Transport Adapter\n *\n * Maps AstraSync credentials to/from A2A task metadata.astrasync block.\n */\n\nimport type { AstraSyncCredentials } from '../types';\n\ninterface A2ATask {\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\ninterface AstraSyncMetadata {\n agentId: string;\n verifyUrl?: string;\n challengeUrl?: string;\n purpose?: { category: string; action?: string };\n duration?: { maxSessionDuration?: number };\n scope?: { jurisdiction?: string };\n}\n\n/**\n * Add AstraSync credentials to an A2A task's metadata block.\n */\nexport function setA2AMetadata(\n task: A2ATask,\n credentials: AstraSyncCredentials,\n): A2ATask {\n const astrasync: AstraSyncMetadata = {\n agentId: credentials.agentId,\n };\n\n if (credentials.verifyUrl) astrasync.verifyUrl = credentials.verifyUrl;\n if (credentials.challengeUrl) astrasync.challengeUrl = credentials.challengeUrl;\n if (credentials.pdlss?.purpose) astrasync.purpose = credentials.pdlss.purpose;\n if (credentials.pdlss?.duration) astrasync.duration = credentials.pdlss.duration;\n if (credentials.pdlss?.scope) astrasync.scope = credentials.pdlss.scope;\n\n return {\n ...task,\n metadata: {\n ...task.metadata,\n astrasync,\n },\n };\n}\n\n/**\n * Extract AstraSync credentials from an A2A task's metadata block.\n */\nexport function extractA2ACredentials(task: A2ATask): AstraSyncCredentials | null {\n const meta = task.metadata?.astrasync as AstraSyncMetadata | undefined;\n if (!meta?.agentId) return null;\n\n const credentials: AstraSyncCredentials = {\n agentId: meta.agentId,\n };\n\n if (meta.verifyUrl) credentials.verifyUrl = meta.verifyUrl;\n if (meta.challengeUrl) credentials.challengeUrl = meta.challengeUrl;\n\n if (meta.purpose || meta.duration || meta.scope) {\n credentials.pdlss = {};\n if (meta.purpose) credentials.pdlss.purpose = meta.purpose;\n if (meta.duration) credentials.pdlss.duration = meta.duration;\n if (meta.scope) credentials.pdlss.scope = meta.scope;\n }\n\n return credentials;\n}\n","/**\n * MCP (Model Context Protocol) Transport Adapter\n *\n * Maps AstraSync credentials to/from MCP params._meta.astrasync block.\n */\n\nimport type { AstraSyncCredentials } from '../types';\n\ninterface McpParams {\n _meta?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\ninterface AstraSyncMeta {\n agentId: string;\n verifyUrl?: string;\n challengeUrl?: string;\n purpose?: { category: string; action?: string };\n duration?: { maxSessionDuration?: number };\n scope?: { jurisdiction?: string };\n}\n\n/**\n * Add AstraSync credentials to MCP params' _meta block.\n */\nexport function setMcpMeta(\n params: McpParams,\n credentials: AstraSyncCredentials,\n): McpParams {\n const astrasync: AstraSyncMeta = {\n agentId: credentials.agentId,\n };\n\n if (credentials.verifyUrl) astrasync.verifyUrl = credentials.verifyUrl;\n if (credentials.challengeUrl) astrasync.challengeUrl = credentials.challengeUrl;\n if (credentials.pdlss?.purpose) astrasync.purpose = credentials.pdlss.purpose;\n if (credentials.pdlss?.duration) astrasync.duration = credentials.pdlss.duration;\n if (credentials.pdlss?.scope) astrasync.scope = credentials.pdlss.scope;\n\n return {\n ...params,\n _meta: {\n ...params._meta,\n astrasync,\n },\n };\n}\n\n/**\n * Extract AstraSync credentials from MCP params' _meta block.\n */\nexport function extractMcpCredentials(params: McpParams): AstraSyncCredentials | null {\n const meta = params._meta?.astrasync as AstraSyncMeta | undefined;\n if (!meta?.agentId) return null;\n\n const credentials: AstraSyncCredentials = {\n agentId: meta.agentId,\n };\n\n if (meta.verifyUrl) credentials.verifyUrl = meta.verifyUrl;\n if (meta.challengeUrl) credentials.challengeUrl = meta.challengeUrl;\n\n if (meta.purpose || meta.duration || meta.scope) {\n credentials.pdlss = {};\n if (meta.purpose) credentials.pdlss.purpose = meta.purpose;\n if (meta.duration) credentials.pdlss.duration = meta.duration;\n if (meta.scope) credentials.pdlss.scope = meta.scope;\n }\n\n return credentials;\n}\n","/**\n * Protocol request -> AstraSync PDLSS purpose category mapping.\n *\n * Per spec v2.6 §7.4.3 commerce purpose mapping table, extended with MPP + x402\n * entries (April 2026 protocol landscape).\n */\n\nexport type CommercePurpose =\n | 'commerce.checkout.create'\n | 'commerce.checkout.update'\n | 'commerce.checkout.confirm'\n | 'commerce.checkout.cancel'\n | 'commerce.payment.execute'\n | 'commerce.payment.stream'\n | 'commerce.delegation.intent'\n | 'commerce.delegation.checkout'\n | 'commerce.delegation.payment'\n | 'commerce.identity_probe'\n | 'commerce.browsing';\n\nconst UCP_ROUTES: Array<{ method: string; pattern: RegExp; purpose: CommercePurpose }> = [\n { method: 'POST', pattern: /^\\/checkout[-_]sessions\\/?$/, purpose: 'commerce.checkout.create' },\n {\n method: 'PUT',\n pattern: /^\\/checkout[-_]sessions\\/[^/]+\\/?$/,\n purpose: 'commerce.checkout.update',\n },\n {\n method: 'POST',\n pattern: /^\\/checkout[-_]sessions\\/[^/]+\\/complete\\/?$/,\n purpose: 'commerce.payment.execute',\n },\n {\n method: 'POST',\n pattern: /^\\/checkout[-_]sessions\\/[^/]+\\/cancel\\/?$/,\n purpose: 'commerce.checkout.cancel',\n },\n];\n\nconst ACP_ROUTES: Array<{ method: string; pattern: RegExp; purpose: CommercePurpose }> = [\n { method: 'POST', pattern: /^\\/checkout_sessions\\/?$/, purpose: 'commerce.checkout.create' },\n {\n method: 'POST',\n pattern: /^\\/checkout_sessions\\/[^/]+\\/?$/,\n purpose: 'commerce.checkout.update',\n },\n {\n method: 'POST',\n pattern: /^\\/checkout_sessions\\/[^/]+\\/complete\\/?$/,\n purpose: 'commerce.payment.execute',\n },\n {\n method: 'POST',\n pattern: /^\\/checkout_sessions\\/[^/]+\\/cancel\\/?$/,\n purpose: 'commerce.checkout.cancel',\n },\n {\n method: 'POST',\n pattern: /^\\/agentic_commerce\\/delegate_payment\\/?$/,\n purpose: 'commerce.delegation.payment',\n },\n];\n\nexport function mapUCPRequestToPurpose(method: string, path: string): CommercePurpose | null {\n const normalizedMethod = method.toUpperCase();\n const normalizedPath = stripQuery(path);\n for (const route of UCP_ROUTES) {\n if (route.method === normalizedMethod && route.pattern.test(normalizedPath)) {\n return route.purpose;\n }\n }\n return null;\n}\n\nexport function mapACPRequestToPurpose(method: string, path: string): CommercePurpose | null {\n const normalizedMethod = method.toUpperCase();\n const normalizedPath = stripQuery(path);\n for (const route of ACP_ROUTES) {\n if (route.method === normalizedMethod && route.pattern.test(normalizedPath)) {\n return route.purpose;\n }\n }\n return null;\n}\n\nexport type AP2MandateType = 'intent_mandate' | 'cart_mandate' | 'payment_mandate';\nexport function mapAP2MandateToPurpose(mandateType: AP2MandateType): CommercePurpose {\n switch (mandateType) {\n case 'intent_mandate':\n return 'commerce.delegation.intent';\n case 'cart_mandate':\n return 'commerce.checkout.confirm';\n case 'payment_mandate':\n return 'commerce.payment.execute';\n }\n}\n\nexport type VIMandateType = 'checkout' | 'payment' | 'checkout.open' | 'payment.open';\nexport function mapVIMandateToPurpose(mandateType: VIMandateType): CommercePurpose {\n switch (mandateType) {\n case 'checkout':\n return 'commerce.checkout.confirm';\n case 'payment':\n return 'commerce.payment.execute';\n case 'checkout.open':\n return 'commerce.delegation.checkout';\n case 'payment.open':\n return 'commerce.delegation.payment';\n }\n}\n\nexport type RFC9421Tag = 'browse' | 'purchase' | undefined;\nexport function mapRFC9421TagToPurpose(tag: RFC9421Tag): CommercePurpose {\n if (tag === 'purchase') return 'commerce.payment.execute';\n return 'commerce.browsing';\n}\n\nexport type MPPIntent = 'charge' | 'session';\nexport function mapMPPRequestToPurpose(\n intent: MPPIntent | undefined,\n amount: number | undefined\n): CommercePurpose {\n if (typeof amount === 'number' && amount === 0) return 'commerce.identity_probe';\n if (intent === 'session') return 'commerce.payment.stream';\n return 'commerce.payment.execute';\n}\n\nexport function mapX402RequestToPurpose(amount: number | undefined): CommercePurpose {\n if (typeof amount === 'number' && amount === 0) return 'commerce.identity_probe';\n return 'commerce.payment.execute';\n}\n\nfunction stripQuery(path: string): string {\n const q = path.indexOf('?');\n return q === -1 ? path : path.slice(0, q);\n}\n\n/**\n * Informational Stripe webhook events surfaced as trust signals on\n * `CommerceContext.trustSignals` but NOT routed to a PDLSS purpose.\n */\nexport const STRIPE_WEBHOOK_INFORMATIONAL_EVENTS = [\n 'payment_intent.succeeded',\n 'payment_intent.payment_failed',\n 'charge.refunded',\n 'checkout.session.completed',\n 'customer.subscription.created',\n] as const;\nexport type StripeWebhookInformationalEvent = (typeof STRIPE_WEBHOOK_INFORMATIONAL_EVENTS)[number];\n\nexport function isStripeWebhookInformational(eventType: string): boolean {\n return (STRIPE_WEBHOOK_INFORMATIONAL_EVENTS as readonly string[]).includes(eventType);\n}\n","/**\n * Per-protocol transaction-value normalization.\n *\n * Each protocol encodes amount/currency differently. This module produces a\n * uniform `TransactionValueContext` with `source` recording the extraction\n * path so trace logs can show where the value came from.\n *\n * Amount unit: \"major units\" (dollars/euros/etc. for fiat; native unit for\n * tokens — we do NOT convert across currencies). UCP/ACP totals are in\n * cents, so we divide by 100. MPP/x402/VI pass through as declared.\n */\n\nexport interface TransactionValueContext {\n protocol: 'vi' | 'ap2' | 'ucp' | 'acp' | 'mpp' | 'x402' | 'agentpay' | 'tap';\n amount: number;\n currency: string;\n source: string;\n}\n\nexport function extractUCPTransactionValue(input: {\n totals?: Array<{ type?: string; amount?: number; currency?: string }>;\n}): TransactionValueContext | null {\n const totals = input.totals ?? [];\n const total = totals.find((t) => t.type === 'total') ?? totals[0];\n if (!total || typeof total.amount !== 'number' || !total.currency) return null;\n return {\n protocol: 'ucp',\n amount: total.amount / 100,\n currency: total.currency,\n source: `totals[type=${total.type ?? 'unknown'}].amount`,\n };\n}\n\nexport function extractACPTransactionValue(input: {\n totals?: Array<{ type?: string; amount?: number; currency?: string }>;\n}): TransactionValueContext | null {\n const totals = input.totals ?? [];\n const total = totals.find((t) => t.type === 'total') ?? totals[0];\n if (!total || typeof total.amount !== 'number' || !total.currency) return null;\n return {\n protocol: 'acp',\n amount: total.amount / 100,\n currency: total.currency,\n source: `totals[type=${total.type ?? 'unknown'}].amount`,\n };\n}\n\nexport interface VIClaimsForValue {\n constraints?: {\n paymentAmount?: { currency?: string; min?: number; max?: number };\n };\n l3aPaymentAmount?: { currency?: string; amount?: number };\n}\n\nexport function extractVITransactionValue(\n claims: VIClaimsForValue\n): TransactionValueContext | null {\n const l3a = claims.l3aPaymentAmount;\n if (l3a && typeof l3a.amount === 'number' && l3a.currency) {\n return {\n protocol: 'vi',\n amount: l3a.amount,\n currency: l3a.currency,\n source: 'L3a.payment.amount',\n };\n }\n const bound = claims.constraints?.paymentAmount;\n if (bound && typeof bound.max === 'number' && bound.currency) {\n return {\n protocol: 'vi',\n amount: bound.max,\n currency: bound.currency,\n source: 'L2.payment.constraints.amount.max',\n };\n }\n return null;\n}\n\nexport interface AP2PaymentMandateForValue {\n payment_details_total?: { amount?: { value?: string | number; currency?: string } };\n}\n\nexport function extractAP2TransactionValue(\n mandate: AP2PaymentMandateForValue | undefined\n): TransactionValueContext | null {\n const amt = mandate?.payment_details_total?.amount;\n if (!amt || !amt.currency) return null;\n const n = typeof amt.value === 'string' ? Number(amt.value) : amt.value;\n if (typeof n !== 'number' || !Number.isFinite(n)) return null;\n return {\n protocol: 'ap2',\n amount: n,\n currency: amt.currency,\n source: 'payment_mandate.payment_details_total.amount',\n };\n}\n\nexport interface MPPChallengeForValue {\n method?: string;\n request?: { amount?: number; currency?: string } & Record<string, unknown>;\n}\n\nexport function extractMPPTransactionValue(\n challenge: MPPChallengeForValue\n): TransactionValueContext | null {\n const req = challenge.request;\n if (!req || typeof req.amount !== 'number' || !req.currency) return null;\n return {\n protocol: 'mpp',\n amount: req.amount,\n currency: req.currency,\n source: `challenge.request.amount (method=${challenge.method ?? 'unknown'})`,\n };\n}\n\nexport interface X402RequestForValue {\n maxAmountRequired?: number;\n amount?: number;\n asset?: string;\n currency?: string;\n}\n\nexport function extractX402TransactionValue(\n req: X402RequestForValue\n): TransactionValueContext | null {\n const amount = req.maxAmountRequired ?? req.amount;\n const currency = req.currency ?? req.asset;\n if (typeof amount !== 'number' || !currency) return null;\n return {\n protocol: 'x402',\n amount,\n currency,\n source: req.maxAmountRequired !== undefined ? 'maxAmountRequired' : 'amount',\n };\n}\n","/**\n * RFC 9421 HTTP Message Signatures parser.\n *\n * Wraps `structured-headers` (transitive dep of http-message-signatures) to\n * parse the Signature-Input and Signature Dictionary headers per RFC 9421 §2.\n *\n * Produces structured metadata (kid, algorithm, covered components, tag,\n * created/expires/nonce, signature bytes) without verifying the signature —\n * verification lives in rfc9421-verify.ts.\n *\n * Shared by:\n * - Agent Pay (Mastercard) — kid resolves via Mastercard Agent Registry\n * - TAP (Visa) — kid resolves via Visa JWKS\n * - Web Bot Auth (generic transport substrate) — kid resolves via\n * /.well-known/http-message-signatures-directory\n */\n\nimport { parseDictionary } from 'structured-headers';\n\nexport interface RFC9421SignatureParams {\n /** The label identifying the signature in the Dictionary header (e.g. \"sig1\"). */\n label: string;\n /** Key ID used to look up the verifying key in the relevant registry. */\n kid: string;\n /** Algorithm declared in the Signature-Input params (e.g. \"ecdsa-p256-sha256\", \"ed25519\"). */\n alg?: string;\n /** Covered components, in order, per RFC 9421 §2.1. */\n covered: string[];\n /** Base64url-encoded signature bytes extracted from the paired Signature header. */\n signatureBase64: string;\n /** Unix seconds when the signature was created. */\n created?: number;\n /** Unix seconds when the signature expires. */\n expires?: number;\n /** Nonce (opaque string) for replay protection. */\n nonce?: string;\n /** Tag parameter. For Agent Pay/TAP this is \"browse\" or \"purchase\"; undefined otherwise. */\n tag?: 'browse' | 'purchase' | string;\n}\n\nexport interface ParsedRFC9421 {\n signatures: RFC9421SignatureParams[];\n}\n\n/**\n * Parse the RFC 9421 Signature-Input and Signature headers from a request or response.\n * Returns all signatures present (a single message may carry multiple labelled signatures).\n *\n * Returns null if either header is missing or malformed.\n */\nexport function parseRFC9421(\n headers: Record<string, string | string[] | undefined>\n): ParsedRFC9421 | null {\n const sigInput = readHeader(headers, 'signature-input');\n const sig = readHeader(headers, 'signature');\n if (!sigInput || !sig) return null;\n\n let inputDict;\n let sigDict;\n try {\n inputDict = parseDictionary(sigInput);\n sigDict = parseDictionary(sig);\n } catch {\n return null;\n }\n\n const signatures: RFC9421SignatureParams[] = [];\n\n for (const [label, entry] of inputDict) {\n // entry.value is the inner list of covered components; entry[1] is the params Map.\n const innerList = Array.isArray(entry)\n ? entry[0]\n : (entry as { value?: unknown; params?: unknown }).value;\n const params = Array.isArray(entry)\n ? entry[1]\n : (entry as { value?: unknown; params?: unknown }).params;\n if (!Array.isArray(innerList) || !params) continue;\n\n const covered: string[] = [];\n for (const item of innerList as Array<[unknown, Map<string, unknown>]>) {\n const [bare] = Array.isArray(item) ? item : [item];\n if (typeof bare === 'string') covered.push(bare);\n else if (bare && typeof bare === 'object' && 'toString' in bare) covered.push(String(bare));\n }\n\n const paramsMap = params as Map<string, unknown>;\n const kid = coerceString(paramsMap.get('keyid'));\n if (!kid) continue;\n\n const sigEntry = sigDict.get(label);\n if (!sigEntry) continue;\n\n const sigBare = Array.isArray(sigEntry) ? sigEntry[0] : (sigEntry as { value?: unknown }).value;\n const signatureBase64 = extractBase64(sigBare);\n if (!signatureBase64) continue;\n\n signatures.push({\n label,\n kid,\n alg: coerceString(paramsMap.get('alg')),\n covered,\n signatureBase64,\n created: coerceNumber(paramsMap.get('created')),\n expires: coerceNumber(paramsMap.get('expires')),\n nonce: coerceString(paramsMap.get('nonce')),\n tag: coerceString(paramsMap.get('tag')),\n });\n }\n\n if (signatures.length === 0) return null;\n return { signatures };\n}\n\nfunction readHeader(\n headers: Record<string, string | string[] | undefined>,\n name: string\n): string | null {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === name) {\n const raw = headers[key];\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw.join(', ');\n return null;\n }\n }\n return null;\n}\n\nfunction coerceString(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (value == null) return undefined;\n if (typeof value === 'object' && 'toString' in (value as object)) {\n const s = String(value);\n return s.length > 0 ? s : undefined;\n }\n return undefined;\n}\n\nfunction coerceNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'bigint') return Number(value);\n return undefined;\n}\n\nfunction extractBase64(value: unknown): string | null {\n if (value instanceof Uint8Array) return bufferToBase64(value);\n if (value instanceof ArrayBuffer) return bufferToBase64(new Uint8Array(value));\n if (ArrayBuffer.isView(value)) {\n const v = value as ArrayBufferView;\n return bufferToBase64(new Uint8Array(v.buffer, v.byteOffset, v.byteLength));\n }\n if (typeof value === 'string') {\n if (value.startsWith(':') && value.endsWith(':')) return value.slice(1, -1);\n return value;\n }\n return null;\n}\n\nfunction bufferToBase64(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString('base64');\n}\n","/**\n * RFC 9421 HTTP Message Signatures verification.\n *\n * Wraps http-message-signatures (dhensby) verifyMessage() with a RegistryResolver\n * hook for kid → JWK lookup. Library handles canonicalization + ES256/EdDSA/\n * HMAC/RSA verification; we supply the key-finding callback and policy around\n * clock skew.\n *\n * Shared by:\n * - Agent Pay (Mastercard) — resolver = createMastercardRegistry\n * - TAP (Visa) — resolver = createVisaRegistry\n * - Web Bot Auth (generic) — resolver = createWebBotAuthRegistry\n */\n\nimport { httpbis, type VerifierFinder, type VerifyingKey } from 'http-message-signatures';\nimport type { JWK } from 'jose';\nimport type { RegistryResolver } from './registry/types';\n\nexport interface RFC9421VerifyRequest {\n method: string;\n url: string;\n headers: Record<string, string | string[]>;\n body?: string;\n}\n\nexport interface RFC9421VerifyOptions {\n resolver: RegistryResolver;\n /** Seconds of tolerance around created/expires. Default 300. */\n clockSkewSec?: number;\n /** Injectable for deterministic tests. */\n now?: () => number;\n}\n\nexport interface RFC9421VerifyResult {\n ok: boolean;\n kid?: string;\n registry?: RegistryResolver['name'];\n algorithm?: string;\n error?: string;\n}\n\nexport async function verifyRFC9421(\n request: RFC9421VerifyRequest,\n options: RFC9421VerifyOptions\n): Promise<RFC9421VerifyResult> {\n const { resolver } = options;\n const tolerance = options.clockSkewSec ?? 300;\n const nowSec = options.now ? options.now() : Math.floor(Date.now() / 1000);\n\n let resolvedKid: string | undefined;\n let resolvedAlg: string | undefined;\n\n const keyLookup: VerifierFinder = async (parameters) => {\n const kid = typeof parameters.keyid === 'string' ? parameters.keyid : undefined;\n if (!kid) return null;\n resolvedKid = kid;\n const alg = typeof parameters.alg === 'string' ? parameters.alg : undefined;\n if (alg) resolvedAlg = alg;\n\n const origin = safeOrigin(request.url);\n const jwk = await resolver.resolve(kid, { origin, algorithm: alg });\n if (!jwk) return null;\n\n // Check clock-skew on this specific signature's created/expires.\n // SignatureParameters may carry Date, number, or ISO string per library.\n const created = toUnixSeconds(parameters.created);\n const expires = toUnixSeconds(parameters.expires);\n if (created !== undefined && Math.abs(nowSec - created) > tolerance) return null;\n if (expires !== undefined && nowSec > expires + tolerance) return null;\n\n return jwkToVerifyingKey(kid, jwk, alg);\n };\n\n try {\n const result = await httpbis.verifyMessage(\n {\n keyLookup,\n },\n normalizeRequest(request)\n );\n if (result === true) {\n return {\n ok: true,\n kid: resolvedKid,\n registry: resolver.name,\n algorithm: resolvedAlg,\n };\n }\n return {\n ok: false,\n kid: resolvedKid,\n registry: resolver.name,\n algorithm: resolvedAlg,\n error: result === false ? 'signature invalid' : 'no signature found',\n };\n } catch (err) {\n return {\n ok: false,\n kid: resolvedKid,\n registry: resolver.name,\n algorithm: resolvedAlg,\n error: err instanceof Error ? err.message : 'verification error',\n };\n }\n}\n\nfunction normalizeRequest(request: RFC9421VerifyRequest): {\n method: string;\n url: string;\n headers: Record<string, string | string[]>;\n} {\n return {\n method: request.method.toUpperCase(),\n url: request.url,\n headers: request.headers,\n };\n}\n\nfunction safeOrigin(url: string): string | undefined {\n try {\n return new URL(url).origin;\n } catch {\n return undefined;\n }\n}\n\nasync function jwkToVerifyingKey(\n id: string,\n jwk: JWK,\n alg: string | undefined\n): Promise<VerifyingKey> {\n const algorithm = alg ?? inferAlgFromJwk(jwk);\n const { subtle } = await getCrypto();\n const importAlg = webCryptoImportAlgFor(algorithm);\n const verifyAlg = webCryptoAlgFor(algorithm);\n if (!importAlg || !verifyAlg) {\n return {\n id,\n algs: alg ? [alg] : undefined,\n verify: async () => false,\n };\n }\n const key = await subtle.importKey('jwk', jwk as JsonWebKey, importAlg, false, ['verify']);\n\n return {\n id,\n algs: alg ? [alg] : undefined,\n verify: async (data: Buffer, signature: Buffer): Promise<boolean> => {\n try {\n return await subtle.verify(verifyAlg, key, toArrayBuffer(signature), toArrayBuffer(data));\n } catch {\n return false;\n }\n },\n };\n}\n\nfunction inferAlgFromJwk(jwk: JWK): string {\n if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519') return 'ed25519';\n if (jwk.kty === 'EC' && jwk.crv === 'P-256') return 'ecdsa-p256-sha256';\n if (jwk.kty === 'EC' && jwk.crv === 'P-384') return 'ecdsa-p384-sha384';\n if (jwk.kty === 'RSA') return 'rsa-v1_5-sha256';\n return 'ecdsa-p256-sha256';\n}\n\nfunction webCryptoAlgFor(\n rfc9421Alg: string\n): AlgorithmIdentifier | EcdsaParams | RsaPssParams | null {\n switch (rfc9421Alg) {\n case 'ed25519':\n return { name: 'Ed25519' };\n case 'ecdsa-p256-sha256':\n return { name: 'ECDSA', hash: 'SHA-256' };\n case 'ecdsa-p384-sha384':\n return { name: 'ECDSA', hash: 'SHA-384' };\n case 'rsa-v1_5-sha256':\n return { name: 'RSASSA-PKCS1-v1_5' };\n case 'rsa-pss-sha512':\n return { name: 'RSA-PSS', saltLength: 64 };\n default:\n return null;\n }\n}\n\nfunction webCryptoImportAlgFor(\n rfc9421Alg: string\n): AlgorithmIdentifier | EcKeyImportParams | RsaHashedImportParams | null {\n switch (rfc9421Alg) {\n case 'ed25519':\n return { name: 'Ed25519' };\n case 'ecdsa-p256-sha256':\n return { name: 'ECDSA', namedCurve: 'P-256' };\n case 'ecdsa-p384-sha384':\n return { name: 'ECDSA', namedCurve: 'P-384' };\n case 'rsa-v1_5-sha256':\n return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' };\n case 'rsa-pss-sha512':\n return { name: 'RSA-PSS', hash: 'SHA-512' };\n default:\n return null;\n }\n}\n\nfunction toArrayBuffer(buf: Buffer): ArrayBuffer {\n const out = new ArrayBuffer(buf.byteLength);\n new Uint8Array(out).set(buf);\n return out;\n}\n\nfunction toUnixSeconds(v: unknown): number | undefined {\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (v instanceof Date) return Math.floor(v.getTime() / 1000);\n if (typeof v === 'string') {\n const parsed = Date.parse(v);\n if (Number.isFinite(parsed)) return Math.floor(parsed / 1000);\n }\n return undefined;\n}\n\nasync function getCrypto(): Promise<{ subtle: SubtleCrypto }> {\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n return { subtle: globalThis.crypto.subtle };\n }\n // Node fallback\n const nodeCrypto = await import('node:crypto');\n return { subtle: nodeCrypto.webcrypto.subtle as SubtleCrypto };\n}\n","/**\n * UCP (Universal Commerce Protocol) checkout session extractor.\n *\n * Google + Shopify spec (ucp.dev). Extracts checkout session context from\n * incoming HTTP requests and, at registration time, validates the\n * `/.well-known/ucp` manifest via AJV against the mirrored JSON schema.\n */\n\nimport { mapUCPRequestToPurpose, type CommercePurpose } from './purpose-mapping';\n\nexport interface UCPTotal {\n type?: string;\n amount?: number;\n currency?: string;\n}\n\nexport interface UCPCheckoutContext {\n sessionId?: string;\n endpoint: string;\n purpose: CommercePurpose | null;\n merchantDomain?: string;\n totals?: UCPTotal[];\n paymentMethod?: string;\n manifestUrl?: string;\n}\n\nexport interface UCPRequestLike {\n method: string;\n url: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n}\n\nexport function extractUCPContext(request: UCPRequestLike): UCPCheckoutContext | null {\n const { method, url } = request;\n if (!method || !url) return null;\n\n const parsedUrl = safeParseUrl(url);\n const path = parsedUrl?.pathname ?? url.split('?')[0];\n\n const purpose = mapUCPRequestToPurpose(method, path);\n const endpoint = `${method.toUpperCase()} ${path}`;\n const sessionId = extractSessionId(path);\n\n const body = (request.body ?? {}) as Record<string, unknown>;\n const totals = Array.isArray(body.totals) ? (body.totals as UCPTotal[]) : undefined;\n const paymentMethod = coerceString(body.payment_method ?? body.paymentMethod);\n const manifestUrl = coerceString(body.manifest_url ?? body.manifestUrl);\n\n const merchantDomain = extractMerchantDomain(body, parsedUrl);\n\n return {\n sessionId,\n endpoint,\n purpose,\n merchantDomain,\n totals,\n paymentMethod,\n manifestUrl,\n };\n}\n\n/**\n * Fetch and parse a UCP manifest at registration time. Returns parsed JSON\n * on success, null on any failure (network, parse, timeout). Does NOT throw.\n *\n * Schema validation is a separate step — see `validateUCPManifest`.\n */\nexport async function fetchUCPManifest(\n manifestUrl: string,\n options: { timeoutMs?: number } = {}\n): Promise<unknown | null> {\n const timeoutMs = options.timeoutMs ?? 3000;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(manifestUrl, { signal: controller.signal });\n if (!res.ok) return null;\n return await res.json();\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Validate a UCP manifest against the minimal shape we care about.\n *\n * The full UCP manifest schema lives upstream (ucp.dev) and is out of scope\n * to mirror here exhaustively. This function checks the structural guarantees\n * we depend on: required top-level fields (version, capabilities, endpoints).\n *\n * For full schema validation, consumers can pass their own AJV compiled\n * validator via `options.validator`.\n */\nexport interface UCPManifestValidationResult {\n ok: boolean;\n errors: string[];\n}\n\nexport function validateUCPManifest(\n manifest: unknown,\n options: { validator?: (m: unknown) => { ok: boolean; errors: string[] } } = {}\n): UCPManifestValidationResult {\n if (options.validator) return options.validator(manifest);\n\n const errors: string[] = [];\n if (!manifest || typeof manifest !== 'object') {\n return { ok: false, errors: ['manifest is not an object'] };\n }\n const m = manifest as Record<string, unknown>;\n if (typeof m.version !== 'string') errors.push('version is required and must be a string');\n if (!Array.isArray(m.capabilities)) errors.push('capabilities must be an array');\n if (!m.endpoints || typeof m.endpoints !== 'object') errors.push('endpoints must be an object');\n return { ok: errors.length === 0, errors };\n}\n\nfunction safeParseUrl(url: string): URL | null {\n try {\n return new URL(url, 'http://placeholder.invalid');\n } catch {\n return null;\n }\n}\n\nfunction extractSessionId(path: string): string | undefined {\n const match = path.match(/\\/checkout[-_]sessions\\/([^/?#]+)/);\n return match?.[1];\n}\n\nfunction extractMerchantDomain(\n body: Record<string, unknown>,\n parsedUrl: URL | null\n): string | undefined {\n const explicit = coerceString(body.merchant_domain ?? body.merchantDomain);\n if (explicit) return explicit;\n if (parsedUrl && parsedUrl.hostname !== 'placeholder.invalid') return parsedUrl.hostname;\n return undefined;\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n","/**\n * ACP (Agentic Commerce Protocol) request extractor.\n *\n * Co-maintained by OpenAI + Stripe. Spec at agenticcommerce.dev.\n *\n * Extracts ACP request context from HTTP requests:\n * - Multi-header parsing: Signature, Timestamp, Idempotency-Key,\n * Authorization: Bearer, API-Version\n * - Endpoint classification: Agentic Checkout (checkout_sessions.*) vs\n * Delegate Payment (agentic_commerce/delegate_payment)\n * - Payment token detection: spt_* (Stripe SharedPaymentToken),\n * vt_* (ACP vault token), unknown\n * - Totals + merchant extraction from body\n *\n * No signature verification here — see acp-verify.ts.\n */\n\nimport { mapACPRequestToPurpose, type CommercePurpose } from './purpose-mapping';\n\nexport type ACPEndpoint =\n | 'checkout_sessions.create'\n | 'checkout_sessions.update'\n | 'checkout_sessions.complete'\n | 'checkout_sessions.cancel'\n | 'delegate_payment'\n | 'unknown';\n\nexport type ACPPaymentTokenType = 'stripe-spt' | 'acp-vt' | 'other' | null;\n\nexport interface ACPTotal {\n type?: string;\n amount?: number;\n currency?: string;\n}\n\nexport interface ACPRequestContext {\n endpoint: ACPEndpoint;\n purpose: CommercePurpose | null;\n sessionId?: string;\n merchantId?: string;\n apiVersion?: string;\n bearer?: string;\n signatureHeader?: string;\n timestampHeader?: string;\n idempotencyKey?: string;\n paymentToken?: {\n raw?: string;\n type: ACPPaymentTokenType;\n provider?: string;\n };\n totals?: ACPTotal[];\n fulfillmentOption?: string;\n rawBody?: string;\n}\n\nexport interface ACPRequestLike {\n method: string;\n url: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n}\n\nexport function extractACPContext(request: ACPRequestLike): ACPRequestContext | null {\n const { method, url } = request;\n if (!method || !url) return null;\n\n const path = stripQuery(url.startsWith('http') ? new URL(url).pathname : url);\n\n const endpoint = classifyEndpoint(method, path);\n const purpose = mapACPRequestToPurpose(method, path);\n const sessionId = extractSessionId(path);\n\n const headers = request.headers ?? {};\n const signatureHeader = readHeader(headers, 'signature');\n const timestampHeader = readHeader(headers, 'timestamp');\n const idempotencyKey = readHeader(headers, 'idempotency-key');\n const apiVersion = readHeader(headers, 'api-version');\n const bearer = extractBearer(readHeader(headers, 'authorization'));\n\n const body = (request.body ?? {}) as Record<string, unknown>;\n const merchantId = coerceString(body.merchant_id ?? body.merchantId);\n const totals = Array.isArray(body.totals) ? (body.totals as ACPTotal[]) : undefined;\n const fulfillmentOption = extractFulfillmentOption(body);\n\n const paymentToken = extractPaymentToken(body);\n\n return {\n endpoint,\n purpose,\n sessionId,\n merchantId,\n apiVersion,\n bearer,\n signatureHeader,\n timestampHeader,\n idempotencyKey,\n paymentToken,\n totals,\n fulfillmentOption,\n rawBody: request.rawBody,\n };\n}\n\nfunction classifyEndpoint(method: string, path: string): ACPEndpoint {\n const m = method.toUpperCase();\n if (m !== 'POST') return 'unknown';\n if (/^\\/agentic_commerce\\/delegate_payment\\/?$/.test(path)) return 'delegate_payment';\n if (/^\\/checkout_sessions\\/?$/.test(path)) return 'checkout_sessions.create';\n if (/^\\/checkout_sessions\\/[^/]+\\/?$/.test(path)) return 'checkout_sessions.update';\n if (/^\\/checkout_sessions\\/[^/]+\\/complete\\/?$/.test(path)) return 'checkout_sessions.complete';\n if (/^\\/checkout_sessions\\/[^/]+\\/cancel\\/?$/.test(path)) return 'checkout_sessions.cancel';\n return 'unknown';\n}\n\nfunction extractSessionId(path: string): string | undefined {\n const match = path.match(/\\/checkout_sessions\\/([^/?#]+)/);\n return match?.[1];\n}\n\nfunction extractBearer(authHeader: string | undefined): string | undefined {\n if (!authHeader) return undefined;\n const match = authHeader.match(/^Bearer\\s+(.+)$/i);\n return match ? match[1].trim() : undefined;\n}\n\nfunction extractPaymentToken(body: Record<string, unknown>): ACPRequestContext['paymentToken'] {\n const paymentData = body.payment_data as Record<string, unknown> | undefined;\n if (!paymentData) return undefined;\n const raw = coerceString(paymentData.token);\n const provider = coerceString(paymentData.provider);\n if (!raw) return { raw: undefined, type: null, provider };\n const type = classifyPaymentToken(raw);\n return { raw, type, provider };\n}\n\nfunction classifyPaymentToken(token: string): ACPPaymentTokenType {\n if (token.startsWith('spt_')) return 'stripe-spt';\n if (token.startsWith('vt_')) return 'acp-vt';\n return 'other';\n}\n\nfunction extractFulfillmentOption(body: Record<string, unknown>): string | undefined {\n const direct = coerceString(body.fulfillment_option ?? body.fulfillmentOption);\n if (direct) return direct;\n const options = body.fulfillment_options;\n if (Array.isArray(options) && options.length > 0) {\n const first = options[0];\n if (first && typeof first === 'object') {\n const id = coerceString((first as Record<string, unknown>).id);\n if (id) return id;\n }\n }\n return undefined;\n}\n\nfunction readHeader(\n headers: Record<string, string | string[] | undefined>,\n name: string\n): string | undefined {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === name) {\n const raw = headers[key];\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw[0];\n }\n }\n return undefined;\n}\n\nfunction stripQuery(path: string): string {\n const q = path.indexOf('?');\n return q === -1 ? path : path.slice(0, q);\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n","/**\n * VI (Verifiable Intent) SD-JWT extraction.\n *\n * Open-sourced 5 March 2026 by Mastercard + Google (v0.1-draft).\n * VI is a 3-layer SD-JWT chain:\n * L1 — issuer → wallet (credential provider)\n * L2 — user → agent (cnf.jwk binding to L3 agent key)\n * L3 — agent → merchant (payment or checkout mandate, split into L3a / L3b\n * cross-referenced via transaction_id)\n *\n * This module does EXTRACTION ONLY — it decodes SD-JWT structure and pulls\n * out the mandate type, kid, executionMode, 8 constraint types, checkoutHash\n * (constraint type 8), transactionId, and raw layers for later verification.\n *\n * Signature verification lives in vi-verify.ts; this module uses @sd-jwt's\n * sync decoder with a SHA-256 hasher for structural parsing only.\n */\n\nimport { splitSdJwt, decodeSdJwtSync } from '@sd-jwt/decode';\nimport { createHash } from 'node:crypto';\nimport type { VIMandateType } from './purpose-mapping';\n\nexport type { VIMandateType };\nexport type VIExecutionMode = 'Immediate' | 'Autonomous' | 'Both';\n\nexport interface VIAllowedParty {\n id?: string;\n name?: string;\n website?: string;\n}\n\nexport interface VILineItem {\n id?: string;\n acceptableItems?: string[];\n quantity?: number;\n}\n\nexport interface VIPaymentAmount {\n currency?: string;\n min?: number;\n max?: number;\n}\n\nexport interface VIBudgetLimit {\n currency?: string;\n max?: number;\n}\n\nexport interface VIRecurrence {\n frequency?: string;\n startDate?: string;\n endDate?: string;\n maxOccurrences?: number;\n}\n\nexport interface VIConstraints {\n allowedMerchants?: VIAllowedParty[];\n allowedPayees?: VIAllowedParty[];\n lineItems?: VILineItem[];\n paymentAmount?: VIPaymentAmount;\n budgetLimit?: VIBudgetLimit;\n recurrence?: VIRecurrence;\n agentRecurrence?: VIRecurrence;\n}\n\nexport interface VIExtractedClaims {\n mandateType: VIMandateType;\n kid?: string;\n executionMode?: VIExecutionMode;\n credentialProvider?: string;\n constraints: VIConstraints;\n /** VI constraint type 8 — SHA-256 of the paired L2 checkout disclosure. */\n checkoutHash?: string;\n transactionId?: string;\n rawLayers: { l1?: string; l2?: string; l3?: string };\n}\n\n/**\n * Extract VI claims from a compact SD-JWT string.\n *\n * Input shape:\n * <jwt>~<disclosure1>~<disclosure2>~...~<kbJwt?>\n *\n * Returns null if parsing fails at any layer. Does not verify signatures.\n */\nexport function extractVIClaims(sdJwtCompact: string): VIExtractedClaims | null {\n if (!sdJwtCompact || typeof sdJwtCompact !== 'string') return null;\n\n let decoded;\n try {\n decoded = decodeSdJwtSync(sdJwtCompact, sha256Sync);\n } catch {\n return null;\n }\n\n const split = safeSplit(sdJwtCompact);\n\n const payload = (decoded.jwt?.payload ?? {}) as Record<string, unknown>;\n const disclosures = decoded.disclosures ?? [];\n\n // Apply disclosures onto payload to resolve _sd references.\n // Disclosure from @sd-jwt/utils has { key, value, digest() } where digest is\n // a function — we only need key+value here, so narrow via a structural cast.\n const claims = applyDisclosures(\n payload,\n disclosures as unknown as Array<{ key?: string; value?: unknown }>\n );\n\n const mandateType = coerceMandateType(\n claims.mandate_type ?? claims.mandateType ?? payload.mandate_type ?? payload.mandateType\n );\n if (!mandateType) return null;\n\n const kid = coerceString(\n (decoded.jwt?.header as Record<string, unknown> | undefined)?.kid ?? claims.kid ?? payload.kid\n );\n\n const executionMode = coerceExecutionMode(claims.execution_mode ?? claims.executionMode);\n const credentialProvider = coerceString(claims.iss ?? payload.iss);\n\n const constraints = extractConstraints(\n (claims.constraints ?? claims.default_constraints ?? {}) as Record<string, unknown>\n );\n\n const transactionId = coerceString(claims.transaction_id ?? claims.transactionId);\n const checkoutHash = coerceString(\n claims.checkout_hash ??\n claims.conditional_transaction_id ??\n (claims.payment_reference as Record<string, unknown> | undefined)?.checkout_hash\n );\n\n return {\n mandateType,\n kid,\n executionMode,\n credentialProvider,\n constraints,\n checkoutHash,\n transactionId,\n rawLayers: split,\n };\n}\n\nfunction safeSplit(compact: string): { l1?: string; l2?: string; l3?: string } {\n try {\n const { jwt, kbJwt } = splitSdJwt(compact);\n // VI layering maps loosely: the outer JWT is L3 (agent mandate), KB-JWT\n // (if present) is the key-binding proof, and disclosures carry L2/L1 fragments.\n return { l3: jwt, l2: kbJwt };\n } catch {\n return {};\n }\n}\n\nfunction applyDisclosures(\n payload: Record<string, unknown>,\n disclosures: Array<{ key?: string; value?: unknown }>\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...payload };\n for (const d of disclosures) {\n if (d.key && d.value !== undefined && !(d.key in result)) {\n result[d.key] = d.value;\n }\n }\n return result;\n}\n\nfunction extractConstraints(raw: Record<string, unknown>): VIConstraints {\n return {\n allowedMerchants: toAllowedPartyArray(raw.allowed_merchants ?? raw.allowedMerchants),\n allowedPayees: toAllowedPartyArray(raw.allowed_payees ?? raw.allowedPayees),\n lineItems: toLineItemArray(raw.line_items ?? raw.lineItems),\n paymentAmount: toPaymentAmount(raw.payment_amount ?? raw.paymentAmount),\n budgetLimit: toBudgetLimit(raw.budget_limit ?? raw.budgetLimit ?? raw.budget),\n recurrence: toRecurrence(raw.recurrence),\n agentRecurrence: toRecurrence(raw.agent_recurrence ?? raw.agentRecurrence),\n };\n}\n\nfunction toAllowedPartyArray(v: unknown): VIAllowedParty[] | undefined {\n if (!Array.isArray(v)) return undefined;\n const out: VIAllowedParty[] = [];\n for (const item of v) {\n if (item && typeof item === 'object') {\n const r = item as Record<string, unknown>;\n out.push({\n id: coerceString(r.id),\n name: coerceString(r.name),\n website: coerceString(r.website),\n });\n }\n }\n return out.length > 0 ? out : undefined;\n}\n\nfunction toLineItemArray(v: unknown): VILineItem[] | undefined {\n if (!Array.isArray(v)) return undefined;\n const out: VILineItem[] = [];\n for (const item of v) {\n if (item && typeof item === 'object') {\n const r = item as Record<string, unknown>;\n const acc = r.acceptable_items ?? r.acceptableItems;\n out.push({\n id: coerceString(r.id),\n acceptableItems: Array.isArray(acc)\n ? (acc.filter((a) => typeof a === 'string') as string[])\n : undefined,\n quantity: coerceNumber(r.quantity),\n });\n }\n }\n return out.length > 0 ? out : undefined;\n}\n\nfunction toPaymentAmount(v: unknown): VIPaymentAmount | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const r = v as Record<string, unknown>;\n return {\n currency: coerceString(r.currency),\n min: coerceNumber(r.min),\n max: coerceNumber(r.max),\n };\n}\n\nfunction toBudgetLimit(v: unknown): VIBudgetLimit | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const r = v as Record<string, unknown>;\n return {\n currency: coerceString(r.currency),\n max: coerceNumber(r.max),\n };\n}\n\nfunction toRecurrence(v: unknown): VIRecurrence | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const r = v as Record<string, unknown>;\n return {\n frequency: coerceString(r.frequency),\n startDate: coerceString(r.start_date ?? r.startDate),\n endDate: coerceString(r.end_date ?? r.endDate),\n maxOccurrences: coerceNumber(r.max_occurrences ?? r.maxOccurrences),\n };\n}\n\nfunction coerceMandateType(v: unknown): VIMandateType | null {\n if (v === 'checkout' || v === 'payment' || v === 'checkout.open' || v === 'payment.open') {\n return v;\n }\n return null;\n}\n\nfunction coerceExecutionMode(v: unknown): VIExecutionMode | undefined {\n return v === 'Immediate' || v === 'Autonomous' || v === 'Both' ? v : undefined;\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n\nfunction coerceNumber(v: unknown): number | undefined {\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (typeof v === 'string') {\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n }\n return undefined;\n}\n\nfunction sha256Sync(data: string | ArrayBuffer): Uint8Array {\n const buf =\n typeof data === 'string' ? Buffer.from(data, 'utf-8') : Buffer.from(new Uint8Array(data));\n const hash = createHash('sha256').update(buf).digest();\n return new Uint8Array(hash.buffer, hash.byteOffset, hash.byteLength);\n}\n","/**\n * Stripe webhook HMAC-SHA256 verifier (inline).\n *\n * Stripe-Signature header format: \"t=TIMESTAMP,v1=HEX_SIGNATURE\"\n * - t: unix seconds when Stripe signed the webhook\n * - v1: HMAC-SHA256(webhook_secret, `${t}.${payload}`) as hex\n *\n * Multiple v1 signatures can coexist during secret rotation; any match wins.\n * Default tolerance on timestamp age: 300s (matches Stripe's own default).\n *\n * Documented at docs.stripe.com — we intentionally inline ~25 LOC rather\n * than pull in the full stripe npm package (MIT but 600KB+ with deps).\n */\n\nimport { createHmac, timingSafeEqual } from 'node:crypto';\n\nexport interface VerifyStripeWebhookResult {\n ok: boolean;\n timestamp?: number;\n error?: string;\n}\n\nexport interface VerifyStripeWebhookOptions {\n toleranceSec?: number;\n /** Injectable for deterministic tests. */\n now?: () => number;\n}\n\nexport function verifyStripeWebhook(\n payload: string,\n signatureHeader: string | undefined,\n secret: string,\n options: VerifyStripeWebhookOptions = {}\n): VerifyStripeWebhookResult {\n if (!signatureHeader) return { ok: false, error: 'missing Stripe-Signature header' };\n if (!secret) return { ok: false, error: 'missing webhook secret' };\n\n const parsed = parseStripeSignature(signatureHeader);\n if (!parsed.timestamp) return { ok: false, error: 'malformed Stripe-Signature (missing t=)' };\n if (parsed.v1Signatures.length === 0) {\n return { ok: false, error: 'malformed Stripe-Signature (no v1=)' };\n }\n\n const tolerance = options.toleranceSec ?? 300;\n const now = options.now ? options.now() : Math.floor(Date.now() / 1000);\n if (Math.abs(now - parsed.timestamp) > tolerance) {\n return {\n ok: false,\n timestamp: parsed.timestamp,\n error: `timestamp outside tolerance (${tolerance}s)`,\n };\n }\n\n const signedPayload = `${parsed.timestamp}.${payload}`;\n const expected = createHmac('sha256', secret).update(signedPayload).digest();\n\n for (const candidateHex of parsed.v1Signatures) {\n const candidate = hexToBuffer(candidateHex);\n if (!candidate) continue;\n if (candidate.length !== expected.length) continue;\n if (timingSafeEqual(candidate, expected)) {\n return { ok: true, timestamp: parsed.timestamp };\n }\n }\n\n return { ok: false, timestamp: parsed.timestamp, error: 'signature mismatch' };\n}\n\ninterface ParsedStripeSignature {\n timestamp: number | null;\n v1Signatures: string[];\n}\n\nfunction parseStripeSignature(header: string): ParsedStripeSignature {\n let timestamp: number | null = null;\n const v1Signatures: string[] = [];\n for (const part of header.split(',')) {\n const [rawKey, rawValue] = part.split('=');\n if (!rawKey || !rawValue) continue;\n const key = rawKey.trim();\n const value = rawValue.trim();\n if (key === 't') {\n const n = Number(value);\n if (Number.isFinite(n)) timestamp = n;\n } else if (key === 'v1') {\n v1Signatures.push(value);\n }\n }\n return { timestamp, v1Signatures };\n}\n\nfunction hexToBuffer(hex: string): Buffer | null {\n if (!/^[0-9a-fA-F]+$/.test(hex) || hex.length % 2 !== 0) return null;\n return Buffer.from(hex, 'hex');\n}\n","/**\n * PDLSS constraint evaluation.\n *\n * Evaluates VI constraint types 1-4 (merchant/payee allowlists, line items,\n * payment amount) + MPP/x402 payment-method allowlist + spending-limit\n * against a transaction context.\n *\n * Types 5/6/7 (budget, recurrence, agent_recurrence) extract through but\n * enforcement is deferred to the cross-merchant budget service (§3.3.15,\n * separate PR). This module returns per-constraint {ok, reason} results\n * so a policy layer can decide hard-deny vs trust-signal.\n */\n\nimport type { VIConstraints, VIAllowedParty, VILineItem, VIPaymentAmount } from './vi';\n\nexport interface TransactionContext {\n amount?: number;\n currency?: string;\n merchant?: { id?: string; website?: string };\n payee?: { id?: string; website?: string };\n lineItems?: Array<{ id?: string; quantity?: number }>;\n /** For MPP / x402 payment-method enforcement. */\n paymentMethod?: string;\n}\n\nexport type ConstraintKey = 'merchant' | 'payee' | 'lineItems' | 'amount' | 'paymentMethod';\n\nexport interface ConstraintResult {\n ok: boolean;\n reason?: string;\n}\n\nexport interface ConstraintEvalResult {\n ok: boolean;\n results: Record<string, ConstraintResult>;\n reasons: string[];\n}\n\nexport interface VIConstraintEvalInput {\n constraints: VIConstraints;\n transaction: TransactionContext;\n}\n\nexport function evaluateVIConstraints(input: VIConstraintEvalInput): ConstraintEvalResult {\n const { constraints, transaction } = input;\n const results: Record<string, ConstraintResult> = {};\n\n if (constraints.allowedMerchants && constraints.allowedMerchants.length > 0) {\n results.merchant = evaluateAllowlist(\n 'merchant',\n constraints.allowedMerchants,\n transaction.merchant\n );\n }\n\n if (constraints.allowedPayees && constraints.allowedPayees.length > 0) {\n results.payee = evaluateAllowlist('payee', constraints.allowedPayees, transaction.payee);\n }\n\n if (constraints.lineItems && constraints.lineItems.length > 0) {\n results.lineItems = evaluateLineItems(constraints.lineItems, transaction.lineItems ?? []);\n }\n\n if (constraints.paymentAmount) {\n results.amount = evaluatePaymentAmount(constraints.paymentAmount, transaction);\n }\n\n const reasons: string[] = [];\n let ok = true;\n for (const [key, r] of Object.entries(results)) {\n if (!r.ok) {\n ok = false;\n reasons.push(r.reason ?? `${key} failed`);\n }\n }\n\n return { ok, results, reasons };\n}\n\nexport interface PaymentMethodAllowlistInput {\n allowedMethods?: string[];\n requestedMethod?: string;\n}\n\nexport function evaluatePaymentMethodAllowlist(\n input: PaymentMethodAllowlistInput\n): ConstraintResult {\n const allow = input.allowedMethods ?? [];\n if (allow.length === 0) return { ok: true };\n if (!input.requestedMethod) {\n return { ok: false, reason: 'no payment method in request; allowlist configured' };\n }\n const lowered = input.requestedMethod.toLowerCase();\n const allowed = allow.some((m) => m.toLowerCase() === lowered);\n if (!allowed) {\n return {\n ok: false,\n reason: `payment method \"${input.requestedMethod}\" not in allowlist [${allow.join(', ')}]`,\n };\n }\n return { ok: true };\n}\n\nexport interface SpendingLimitInput {\n limit?: { amount?: number; currency?: string };\n requested?: { amount?: number; currency?: string };\n}\n\nexport function evaluateSpendingLimit(input: SpendingLimitInput): ConstraintResult {\n const { limit, requested } = input;\n if (!limit || typeof limit.amount !== 'number') return { ok: true };\n if (!requested || typeof requested.amount !== 'number') return { ok: true };\n if (limit.currency && requested.currency && limit.currency !== requested.currency) {\n return {\n ok: false,\n reason: `currency mismatch: limit ${limit.currency} vs requested ${requested.currency}`,\n };\n }\n if (requested.amount > limit.amount) {\n return {\n ok: false,\n reason:\n `requested ${requested.amount} ${requested.currency ?? ''} exceeds limit ${limit.amount} ${limit.currency ?? ''}`.trim(),\n };\n }\n return { ok: true };\n}\n\nfunction evaluateAllowlist(\n kind: 'merchant' | 'payee',\n allowlist: VIAllowedParty[],\n actual: { id?: string; website?: string } | undefined\n): ConstraintResult {\n if (!actual || (!actual.id && !actual.website)) {\n return { ok: false, reason: `no ${kind} in transaction; allowlist configured` };\n }\n for (const entry of allowlist) {\n if (entry.id && actual.id && entry.id === actual.id) return { ok: true };\n if (entry.website && actual.website && domainsMatch(entry.website, actual.website)) {\n return { ok: true };\n }\n }\n const allowedDescriptors = allowlist.map(describeParty).join(', ');\n const actualDescriptor = describeParty(actual);\n return {\n ok: false,\n reason: `${kind} ${actualDescriptor} not in allowlist [${allowedDescriptors}]`,\n };\n}\n\nfunction evaluateLineItems(\n allowlist: VILineItem[],\n actualItems: Array<{ id?: string; quantity?: number }>\n): ConstraintResult {\n if (actualItems.length === 0) {\n return { ok: false, reason: 'no line items in transaction; allowlist configured' };\n }\n const reasons: string[] = [];\n for (const item of actualItems) {\n const match = allowlist.find(\n (a) => (a.id && a.id === item.id) || (a.acceptableItems ?? []).includes(item.id ?? '')\n );\n if (!match) {\n reasons.push(`line item \"${item.id ?? '(unnamed)'}\" not in allowlist`);\n continue;\n }\n if (\n typeof match.quantity === 'number' &&\n typeof item.quantity === 'number' &&\n item.quantity > match.quantity\n ) {\n reasons.push(\n `line item \"${item.id}\" quantity ${item.quantity} exceeds allowed ${match.quantity}`\n );\n }\n }\n return reasons.length === 0 ? { ok: true } : { ok: false, reason: reasons.join('; ') };\n}\n\nfunction evaluatePaymentAmount(\n bound: VIPaymentAmount,\n transaction: TransactionContext\n): ConstraintResult {\n if (typeof transaction.amount !== 'number') {\n return { ok: false, reason: 'no amount in transaction; paymentAmount bound configured' };\n }\n if (bound.currency && transaction.currency && bound.currency !== transaction.currency) {\n return {\n ok: false,\n reason: `currency mismatch: bound ${bound.currency} vs transaction ${transaction.currency}`,\n };\n }\n if (typeof bound.min === 'number' && transaction.amount < bound.min) {\n return {\n ok: false,\n reason: `amount ${transaction.amount} below min ${bound.min}`,\n };\n }\n if (typeof bound.max === 'number' && transaction.amount > bound.max) {\n return {\n ok: false,\n reason: `amount ${transaction.amount} above max ${bound.max}`,\n };\n }\n return { ok: true };\n}\n\nfunction domainsMatch(allow: string, actual: string): boolean {\n const a = normalizeDomain(allow);\n const b = normalizeDomain(actual);\n return a === b || b.endsWith(`.${a}`);\n}\n\nfunction normalizeDomain(value: string): string {\n try {\n const withScheme = /^https?:\\/\\//.test(value) ? value : `https://${value}`;\n return new URL(withScheme).hostname.toLowerCase();\n } catch {\n return value.toLowerCase();\n }\n}\n\nfunction describeParty(party: { id?: string; name?: string; website?: string }): string {\n if (party.id) return `id:${party.id}`;\n if (party.website) return party.website;\n if (party.name) return party.name;\n return '(unnamed)';\n}\n","/**\n * Cross-protocol agent identity binding.\n *\n * Every commerce layer claims an agent identity differently:\n * - VI L3 kid (SD-JWT header)\n * - AP2 agent_id (mandate payload)\n * - ACP Authorization: Bearer token (merchant-issued pre-shared)\n * - MPP Credential `source` field (DID or chain-native key)\n * - x402 client wallet address\n * - RFC 9421 kid (Agent Pay / TAP / Web Bot Auth)\n *\n * This module maps any such claim to a single AstraSync agent via a\n * caller-supplied resolver (typically delegates to the counterparty service),\n * then flags whether multiple claims on the same request resolve to different\n * agents (a trust signal for PDLSS).\n *\n * This is AstraSync whitespace — no vendor owns multi-protocol identity\n * unification.\n */\n\nexport interface IdentityClaim {\n /** Originating protocol label: 'vi' | 'ap2' | 'acp' | 'mpp' | 'x402' | 'agentpay' | 'tap' | 'webbotauth' */\n protocol: string;\n /** Claim field name, e.g. 'kid', 'agent_id', 'source', 'bearer'. */\n field: string;\n /** Claim value as presented on the wire. */\n value: string;\n}\n\nexport interface IdentityBindingResult {\n claims: IdentityClaim[];\n mappedAstraSyncAgentId?: string;\n /**\n * True when two or more claims resolve to different AstraSync agents.\n * Surfaced as a trust signal rather than an auto-deny — legitimate flows\n * (e.g. delegate payments) can legitimately carry multiple identities.\n */\n mismatchAcrossLayers: boolean;\n /** Per-claim resolution result for audit / debugging. */\n resolutions: Array<{ claim: IdentityClaim; agentId: string | null }>;\n}\n\nexport type IdentityResolver = (claim: IdentityClaim) => Promise<string | null>;\n\nexport async function bindIdentity(\n claims: IdentityClaim[],\n resolver: IdentityResolver\n): Promise<IdentityBindingResult> {\n const resolutions: Array<{ claim: IdentityClaim; agentId: string | null }> = [];\n for (const claim of claims) {\n if (!claim.value) {\n resolutions.push({ claim, agentId: null });\n continue;\n }\n const agentId = await resolver(claim);\n resolutions.push({ claim, agentId });\n }\n\n const resolvedIds = resolutions\n .map((r) => r.agentId)\n .filter((id): id is string => typeof id === 'string' && id.length > 0);\n\n const unique = Array.from(new Set(resolvedIds));\n const mismatchAcrossLayers = unique.length > 1;\n const mappedAstraSyncAgentId = unique.length === 1 ? unique[0] : undefined;\n\n return {\n claims,\n mappedAstraSyncAgentId,\n mismatchAcrossLayers,\n resolutions,\n };\n}\n\n/**\n * Helper constructors — keep protocol/field strings consistent across the\n * codebase and make tests readable.\n */\nexport const claim = {\n viKid: (value: string): IdentityClaim => ({ protocol: 'vi', field: 'kid', value }),\n ap2AgentId: (value: string): IdentityClaim => ({ protocol: 'ap2', field: 'agent_id', value }),\n acpBearer: (value: string): IdentityClaim => ({ protocol: 'acp', field: 'bearer', value }),\n mppSource: (value: string): IdentityClaim => ({ protocol: 'mpp', field: 'source', value }),\n x402Wallet: (value: string): IdentityClaim => ({ protocol: 'x402', field: 'wallet', value }),\n agentPayKid: (value: string): IdentityClaim => ({ protocol: 'agentpay', field: 'kid', value }),\n tapKid: (value: string): IdentityClaim => ({ protocol: 'tap', field: 'kid', value }),\n webBotAuthKid: (value: string): IdentityClaim => ({\n protocol: 'webbotauth',\n field: 'kid',\n value,\n }),\n};\n","/**\n * AP2 (Agent Payments Protocol) mandate extraction.\n *\n * Google-led, launched 3 April 2026 with 60+ partners (Mastercard, PayPal,\n * Coinbase, AmEx, Revolut, UnionPay, ...). AP2 ships three mandate types as\n * SD-JWTs in series:\n * - intent_mandate — user declares intent (amount, merchant category, etc.)\n * - cart_mandate — user approves a cart (specific items, totals)\n * - payment_mandate — authorizes the actual payment rail\n *\n * Mandates are cross-referenced via ids; each is an SD-JWT over ES256 (or\n * equivalent). We decode via @sd-jwt/decode and extract the AP2-specific\n * shape — verification lives in ap2-verify.ts.\n */\n\nimport { decodeSdJwtSync } from '@sd-jwt/decode';\nimport { createHash } from 'node:crypto';\nimport type { AP2MandateType } from './purpose-mapping';\n\nexport type { AP2MandateType };\n\nexport interface AP2PaymentDetailsTotal {\n amount?: { value?: string | number; currency?: string };\n label?: string;\n}\n\nexport interface AP2IntentMandateClaims {\n type: 'intent_mandate';\n agent_id?: string;\n user_id?: string;\n merchant_category?: string;\n allowedMerchantDomains?: string[];\n paymentMethods?: string[];\n expires?: string;\n payment_details_total?: AP2PaymentDetailsTotal;\n raw: Record<string, unknown>;\n}\n\nexport interface AP2CartMandateClaims {\n type: 'cart_mandate';\n agent_id?: string;\n intent_mandate_id?: string;\n merchant_id?: string;\n line_items?: Array<{\n id?: string;\n quantity?: number;\n price?: { value?: string | number; currency?: string };\n }>;\n payment_details_total?: AP2PaymentDetailsTotal;\n expires?: string;\n raw: Record<string, unknown>;\n}\n\nexport interface AP2PaymentMandateClaims {\n type: 'payment_mandate';\n agent_id?: string;\n cart_mandate_id?: string;\n payment_method?: string;\n payment_details_total?: AP2PaymentDetailsTotal;\n credential_provider?: string;\n raw: Record<string, unknown>;\n}\n\nexport type AP2MandateClaims =\n | AP2IntentMandateClaims\n | AP2CartMandateClaims\n | AP2PaymentMandateClaims;\n\nexport interface AP2MandateTriple {\n intent?: AP2IntentMandateClaims;\n cart?: AP2CartMandateClaims;\n payment?: AP2PaymentMandateClaims;\n rawLayers: { intentJwt?: string; cartJwt?: string; paymentJwt?: string };\n}\n\n/**\n * Extract a single AP2 mandate from a compact SD-JWT.\n * Returns null if the SD-JWT is malformed or lacks a recognized type field.\n */\nexport function extractAP2Mandate(sdJwtCompact: string): AP2MandateClaims | null {\n if (!sdJwtCompact || typeof sdJwtCompact !== 'string') return null;\n\n let decoded;\n try {\n decoded = decodeSdJwtSync(sdJwtCompact, sha256Sync);\n } catch {\n return null;\n }\n\n const payload = (decoded.jwt?.payload ?? {}) as Record<string, unknown>;\n const disclosures = decoded.disclosures ?? [];\n const claims = applyDisclosures(\n payload,\n disclosures as unknown as Array<{ key?: string; value?: unknown }>\n );\n\n const type = coerceMandateType(claims.type ?? claims.mandate_type ?? claims.mandateType);\n if (!type) return null;\n\n if (type === 'intent_mandate') return buildIntent(claims);\n if (type === 'cart_mandate') return buildCart(claims);\n return buildPayment(claims);\n}\n\nexport interface AP2MandateTripleInput {\n intent?: string;\n cart?: string;\n payment?: string;\n}\n\n/**\n * Extract an intent / cart / payment triple, returning whichever are present.\n * Does NOT enforce cross-reference consistency — that's ap2-verify.ts's job.\n */\nexport function extractAP2Mandates(input: AP2MandateTripleInput): AP2MandateTriple {\n const intent = input.intent\n ? (extractAP2Mandate(input.intent) as AP2IntentMandateClaims | null)\n : null;\n const cart = input.cart ? (extractAP2Mandate(input.cart) as AP2CartMandateClaims | null) : null;\n const payment = input.payment\n ? (extractAP2Mandate(input.payment) as AP2PaymentMandateClaims | null)\n : null;\n return {\n intent: intent ?? undefined,\n cart: cart ?? undefined,\n payment: payment ?? undefined,\n rawLayers: {\n intentJwt: input.intent,\n cartJwt: input.cart,\n paymentJwt: input.payment,\n },\n };\n}\n\nfunction buildIntent(claims: Record<string, unknown>): AP2IntentMandateClaims {\n return {\n type: 'intent_mandate',\n agent_id: coerceString(claims.agent_id ?? claims.agentId),\n user_id: coerceString(claims.user_id ?? claims.userId ?? claims.sub),\n merchant_category: coerceString(claims.merchant_category ?? claims.merchantCategory),\n allowedMerchantDomains: toStringArray(\n claims.allowed_merchant_domains ?? claims.allowedMerchantDomains\n ),\n paymentMethods: toStringArray(claims.payment_methods ?? claims.paymentMethods),\n expires: coerceString(claims.expires ?? claims.exp),\n payment_details_total: toPaymentDetails(claims.payment_details_total ?? claims.total),\n raw: claims,\n };\n}\n\nfunction buildCart(claims: Record<string, unknown>): AP2CartMandateClaims {\n return {\n type: 'cart_mandate',\n agent_id: coerceString(claims.agent_id ?? claims.agentId),\n intent_mandate_id: coerceString(claims.intent_mandate_id ?? claims.intentMandateId),\n merchant_id: coerceString(claims.merchant_id ?? claims.merchantId),\n line_items: toLineItems(claims.line_items ?? claims.lineItems),\n payment_details_total: toPaymentDetails(claims.payment_details_total ?? claims.total),\n expires: coerceString(claims.expires ?? claims.exp),\n raw: claims,\n };\n}\n\nfunction buildPayment(claims: Record<string, unknown>): AP2PaymentMandateClaims {\n return {\n type: 'payment_mandate',\n agent_id: coerceString(claims.agent_id ?? claims.agentId),\n cart_mandate_id: coerceString(claims.cart_mandate_id ?? claims.cartMandateId),\n payment_method: coerceString(claims.payment_method ?? claims.paymentMethod),\n payment_details_total: toPaymentDetails(claims.payment_details_total ?? claims.total),\n credential_provider: coerceString(claims.credential_provider ?? claims.credentialProvider),\n raw: claims,\n };\n}\n\nfunction toPaymentDetails(v: unknown): AP2PaymentDetailsTotal | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const r = v as Record<string, unknown>;\n const amount = r.amount as Record<string, unknown> | undefined;\n return {\n amount: amount\n ? {\n value: coerceStringOrNumber(amount.value),\n currency: coerceString(amount.currency),\n }\n : undefined,\n label: coerceString(r.label),\n };\n}\n\nfunction toLineItems(v: unknown): AP2CartMandateClaims['line_items'] {\n if (!Array.isArray(v)) return undefined;\n const items: NonNullable<AP2CartMandateClaims['line_items']> = [];\n for (const item of v) {\n if (!item || typeof item !== 'object') continue;\n const r = item as Record<string, unknown>;\n const price = r.price as Record<string, unknown> | undefined;\n items.push({\n id: coerceString(r.id),\n quantity: coerceNumber(r.quantity),\n price: price\n ? {\n value: coerceStringOrNumber(price.value),\n currency: coerceString(price.currency),\n }\n : undefined,\n });\n }\n return items.length > 0 ? items : undefined;\n}\n\nfunction toStringArray(v: unknown): string[] | undefined {\n if (!Array.isArray(v)) return undefined;\n const out = v.filter((i): i is string => typeof i === 'string' && i.length > 0);\n return out.length > 0 ? out : undefined;\n}\n\nfunction applyDisclosures(\n payload: Record<string, unknown>,\n disclosures: Array<{ key?: string; value?: unknown }>\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...payload };\n for (const d of disclosures) {\n if (d.key && d.value !== undefined && !(d.key in result)) {\n result[d.key] = d.value;\n }\n }\n return result;\n}\n\nfunction coerceMandateType(v: unknown): AP2MandateType | null {\n if (v === 'intent_mandate' || v === 'cart_mandate' || v === 'payment_mandate') return v;\n return null;\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n\nfunction coerceNumber(v: unknown): number | undefined {\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (typeof v === 'string') {\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n }\n return undefined;\n}\n\nfunction coerceStringOrNumber(v: unknown): string | number | undefined {\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (typeof v === 'string' && v.length > 0) return v;\n return undefined;\n}\n\nfunction sha256Sync(data: string | ArrayBuffer): Uint8Array {\n const buf =\n typeof data === 'string' ? Buffer.from(data, 'utf-8') : Buffer.from(new Uint8Array(data));\n const hash = createHash('sha256').update(buf).digest();\n return new Uint8Array(hash.buffer, hash.byteOffset, hash.byteLength);\n}\n","/**\n * AP2 mandate chain verification.\n *\n * Checks the cross-reference consistency of an intent → cart → payment\n * triple. Does NOT verify cryptographic signatures here (that's a call to\n * @sd-jwt/core which needs the agent's / CP's public key; expose via a\n * verifier callback so pipeline can plug in the right resolver).\n *\n * Rules (per AP2 spec v0.1-draft):\n * - cart.intent_mandate_id must equal the intent mandate's canonical id (if present)\n * - payment.cart_mandate_id must equal the cart mandate's canonical id (if present)\n * - agent_id must match across all three layers\n * - payment_method in payment mandate must be in intent.paymentMethods (if declared)\n * - cart totals must not exceed intent totals (if both declared in same currency)\n * - no mandate may be expired (beyond clock skew)\n */\n\nimport type { AP2MandateTriple } from './ap2';\n\nexport interface AP2VerifyInput {\n triple: AP2MandateTriple;\n clockSkewSec?: number;\n now?: () => number;\n}\n\nexport interface AP2ChainResult {\n ok: boolean;\n checks: {\n intentPresent: boolean;\n cartRefOk: boolean;\n paymentRefOk: boolean;\n agentIdContinuity: boolean;\n paymentMethodAllowed: boolean;\n totalsConsistent: boolean;\n expiryOk: boolean;\n };\n agentId?: string;\n errors: string[];\n}\n\nexport function verifyAP2Chain(input: AP2VerifyInput): AP2ChainResult {\n const { triple } = input;\n const errors: string[] = [];\n\n const intentPresent = triple.intent !== undefined;\n const cartRefOk = checkCartRef(triple, errors);\n const paymentRefOk = checkPaymentRef(triple, errors);\n const { ok: agentIdContinuity, agentId } = checkAgentContinuity(triple, errors);\n const paymentMethodAllowed = checkPaymentMethod(triple, errors);\n const totalsConsistent = checkTotals(triple, errors);\n const expiryOk = checkExpiries(triple, input.clockSkewSec ?? 300, input.now, errors);\n\n const ok =\n cartRefOk &&\n paymentRefOk &&\n agentIdContinuity &&\n paymentMethodAllowed &&\n totalsConsistent &&\n expiryOk;\n\n return {\n ok,\n checks: {\n intentPresent,\n cartRefOk,\n paymentRefOk,\n agentIdContinuity,\n paymentMethodAllowed,\n totalsConsistent,\n expiryOk,\n },\n agentId,\n errors,\n };\n}\n\nfunction checkCartRef(triple: AP2MandateTriple, errors: string[]): boolean {\n const cart = triple.cart;\n if (!cart) return true;\n if (!cart.intent_mandate_id) return true;\n const intentId = triple.intent?.raw?.id as string | undefined;\n if (intentId && cart.intent_mandate_id !== intentId) {\n errors.push(\n `cart.intent_mandate_id (${cart.intent_mandate_id}) does not match intent.id (${intentId})`\n );\n return false;\n }\n return true;\n}\n\nfunction checkPaymentRef(triple: AP2MandateTriple, errors: string[]): boolean {\n const payment = triple.payment;\n if (!payment) return true;\n if (!payment.cart_mandate_id) return true;\n const cartId = triple.cart?.raw?.id as string | undefined;\n if (cartId && payment.cart_mandate_id !== cartId) {\n errors.push(\n `payment.cart_mandate_id (${payment.cart_mandate_id}) does not match cart.id (${cartId})`\n );\n return false;\n }\n return true;\n}\n\nfunction checkAgentContinuity(\n triple: AP2MandateTriple,\n errors: string[]\n): { ok: boolean; agentId?: string } {\n const ids = [triple.intent?.agent_id, triple.cart?.agent_id, triple.payment?.agent_id].filter(\n (id): id is string => typeof id === 'string' && id.length > 0\n );\n if (ids.length === 0) return { ok: true };\n const unique = new Set(ids);\n if (unique.size > 1) {\n errors.push(`agent_id mismatch across mandates: ${Array.from(unique).join(', ')}`);\n return { ok: false, agentId: undefined };\n }\n return { ok: true, agentId: ids[0] };\n}\n\nfunction checkPaymentMethod(triple: AP2MandateTriple, errors: string[]): boolean {\n const paymentMethod = triple.payment?.payment_method;\n const allowed = triple.intent?.paymentMethods;\n if (!paymentMethod || !allowed || allowed.length === 0) return true;\n if (!allowed.includes(paymentMethod)) {\n errors.push(\n `payment_method \"${paymentMethod}\" not in intent.paymentMethods [${allowed.join(', ')}]`\n );\n return false;\n }\n return true;\n}\n\nfunction checkTotals(triple: AP2MandateTriple, errors: string[]): boolean {\n const intentTotal = toNumericAmount(triple.intent?.payment_details_total);\n const cartTotal = toNumericAmount(triple.cart?.payment_details_total);\n const paymentTotal = toNumericAmount(triple.payment?.payment_details_total);\n\n if (intentTotal && cartTotal && intentTotal.currency === cartTotal.currency) {\n if (cartTotal.value > intentTotal.value) {\n errors.push(\n `cart total ${cartTotal.value} ${cartTotal.currency} exceeds intent cap ${intentTotal.value}`\n );\n return false;\n }\n }\n if (cartTotal && paymentTotal && cartTotal.currency === paymentTotal.currency) {\n if (paymentTotal.value > cartTotal.value) {\n errors.push(\n `payment total ${paymentTotal.value} ${paymentTotal.currency} exceeds cart total ${cartTotal.value}`\n );\n return false;\n }\n }\n return true;\n}\n\nfunction checkExpiries(\n triple: AP2MandateTriple,\n toleranceSec: number,\n nowFn: (() => number) | undefined,\n errors: string[]\n): boolean {\n const now = nowFn ? nowFn() : Math.floor(Date.now() / 1000);\n let ok = true;\n for (const [name, mandate] of [\n ['intent', triple.intent],\n ['cart', triple.cart],\n ] as const) {\n if (!mandate?.expires) continue;\n const parsed = parseExpiry(mandate.expires);\n if (parsed === null) {\n errors.push(`${name}.expires unparseable`);\n ok = false;\n continue;\n }\n if (now > parsed + toleranceSec) {\n errors.push(`${name} mandate expired at ${mandate.expires}`);\n ok = false;\n }\n }\n return ok;\n}\n\nfunction toNumericAmount(\n total: import('./ap2').AP2PaymentDetailsTotal | undefined\n): { value: number; currency: string } | null {\n if (!total?.amount?.value || !total.amount.currency) return null;\n const n =\n typeof total.amount.value === 'string' ? Number(total.amount.value) : total.amount.value;\n if (!Number.isFinite(n)) return null;\n return { value: n, currency: total.amount.currency };\n}\n\nfunction parseExpiry(value: string): number | null {\n const asInt = Number(value);\n if (Number.isFinite(asInt) && asInt > 0) {\n return asInt >= 1e12 ? Math.floor(asInt / 1000) : Math.floor(asInt);\n }\n const parsedDate = Date.parse(value);\n if (Number.isFinite(parsedDate)) return Math.floor(parsedDate / 1000);\n return null;\n}\n","/**\n * ACP detached-JSON-signature verifier.\n *\n * ACP (Agentic Commerce Protocol, OpenAI + Stripe) uses detached JSON\n * signatures over request bodies. The public signature algorithm is NOT\n * specified in open docs as of April 2026 (docs.stripe.com/agentic-commerce/*\n * is Private Preview). We implement Ed25519 and ES256 candidates against\n * whichever public key the caller supplies, and report algorithm-unsupported\n * as a trust signal rather than a hard fail so policy can weight it.\n *\n * Timestamp freshness (>300s default) IS a hard fail — prevents replay.\n *\n * Bearer-token → AstraSync agent binding is delegated to caller-supplied\n * resolver (typically the counterparty service).\n */\n\nimport type { JWK } from 'jose';\n\nexport type ACPSignatureAlgorithm = 'ed25519' | 'es256' | 'unsupported';\n\nexport interface ACPVerifyInput {\n /** Raw request body over which the signature was computed. */\n rawBody: string;\n /** Value of the Signature header. Expected to be base64 (either standard or url). */\n signatureHeader?: string;\n /** Value of the Timestamp header (unix seconds as string, or ISO 8601). */\n timestampHeader?: string;\n /** Candidate public keys to try. First matching algorithm wins. */\n candidateKeys: Array<{ jwk: JWK; alg?: ACPSignatureAlgorithm | string }>;\n /** Clock skew tolerance in seconds (default 300). */\n clockSkewSec?: number;\n /** Injectable now for tests. */\n now?: () => number;\n}\n\nexport interface ACPVerifyResult {\n ok: boolean;\n algorithm?: ACPSignatureAlgorithm;\n error?: string;\n /** True when timestamp is outside tolerance. */\n timestampStale?: boolean;\n}\n\nexport async function verifyACPSignature(input: ACPVerifyInput): Promise<ACPVerifyResult> {\n if (!input.signatureHeader) {\n return { ok: false, error: 'missing Signature header' };\n }\n\n const freshness = checkTimestamp(input.timestampHeader, input.clockSkewSec ?? 300, input.now);\n if (!freshness.ok) {\n return { ok: false, error: freshness.error, timestampStale: true };\n }\n\n const signatureBytes = decodeBase64(input.signatureHeader);\n if (!signatureBytes) {\n return { ok: false, error: 'signature header is not valid base64' };\n }\n\n const bodyBytes = new TextEncoder().encode(input.rawBody);\n const { subtle } = await getSubtle();\n\n for (const candidate of input.candidateKeys) {\n const declaredAlg = normalizeAlgorithm(candidate.alg);\n const algsToTry: ACPSignatureAlgorithm[] =\n declaredAlg && declaredAlg !== 'unsupported' ? [declaredAlg] : ['ed25519', 'es256'];\n\n for (const alg of algsToTry) {\n try {\n const verified = await tryVerify(subtle, candidate.jwk, signatureBytes, bodyBytes, alg);\n if (verified) return { ok: true, algorithm: alg };\n } catch {\n // swallow per-candidate errors; try next algorithm/candidate\n }\n }\n }\n\n return {\n ok: false,\n algorithm: 'unsupported',\n error: 'no candidate key verified the signature under Ed25519 or ES256',\n };\n}\n\nasync function tryVerify(\n subtle: SubtleCrypto,\n jwk: JWK,\n signature: Uint8Array,\n body: Uint8Array,\n alg: ACPSignatureAlgorithm\n): Promise<boolean> {\n if (alg === 'ed25519') {\n if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') return false;\n const key = await subtle.importKey('jwk', jwk as JsonWebKey, { name: 'Ed25519' }, false, [\n 'verify',\n ]);\n return await subtle.verify({ name: 'Ed25519' }, key, toBuf(signature), toBuf(body));\n }\n if (alg === 'es256') {\n if (jwk.kty !== 'EC' || jwk.crv !== 'P-256') return false;\n const key = await subtle.importKey(\n 'jwk',\n jwk as JsonWebKey,\n { name: 'ECDSA', namedCurve: 'P-256' },\n false,\n ['verify']\n );\n return await subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n key,\n toBuf(signature),\n toBuf(body)\n );\n }\n return false;\n}\n\nfunction toBuf(bytes: Uint8Array): ArrayBuffer {\n const out = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(out).set(bytes);\n return out;\n}\n\nfunction checkTimestamp(\n headerValue: string | undefined,\n toleranceSec: number,\n nowFn?: () => number\n): { ok: true } | { ok: false; error: string } {\n if (!headerValue) return { ok: false, error: 'missing Timestamp header' };\n const ts = parseTimestamp(headerValue);\n if (ts === null) return { ok: false, error: 'unparseable Timestamp header' };\n const now = nowFn ? nowFn() : Math.floor(Date.now() / 1000);\n if (Math.abs(now - ts) > toleranceSec) {\n return { ok: false, error: `timestamp outside ${toleranceSec}s tolerance` };\n }\n return { ok: true };\n}\n\nfunction parseTimestamp(value: string): number | null {\n const asInt = Number(value);\n if (Number.isFinite(asInt) && asInt > 0) {\n // Treat >= 1e12 as milliseconds; otherwise seconds.\n return asInt >= 1e12 ? Math.floor(asInt / 1000) : Math.floor(asInt);\n }\n const parsedDate = Date.parse(value);\n if (Number.isFinite(parsedDate)) return Math.floor(parsedDate / 1000);\n return null;\n}\n\nfunction normalizeAlgorithm(alg: string | undefined): ACPSignatureAlgorithm | undefined {\n if (!alg) return undefined;\n const lowered = alg.toLowerCase();\n if (lowered === 'ed25519' || lowered === 'eddsa') return 'ed25519';\n if (lowered === 'es256' || lowered.startsWith('ecdsa-p256')) return 'es256';\n return 'unsupported';\n}\n\nfunction decodeBase64(value: string): Uint8Array | null {\n try {\n // Accept either standard base64 or url-safe; jose and node both accept both via Buffer.\n const normalized = value.replace(/-/g, '+').replace(/_/g, '/');\n const pad = normalized.length % 4 === 0 ? '' : '='.repeat(4 - (normalized.length % 4));\n return new Uint8Array(Buffer.from(normalized + pad, 'base64'));\n } catch {\n return null;\n }\n}\n\nasync function getSubtle(): Promise<{ subtle: SubtleCrypto }> {\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n return { subtle: globalThis.crypto.subtle };\n }\n const nodeCrypto = await import('node:crypto');\n return { subtle: nodeCrypto.webcrypto.subtle as SubtleCrypto };\n}\n","/**\n * MPP (Machine Payments Protocol) extractor.\n *\n * Wraps mppx (wevm) — pinned to 0.5.13, wrapped behind this adapter so\n * upgrades localise here. MPP launched March 18 2026 (Stripe + Tempo +\n * Paradigm), IETF draft-ryan-httpauth-payment-01.\n *\n * Flow:\n * Client → GET /resource\n * Server → 402 + WWW-Authenticate: Payment id=..., realm=..., method=tempo|stripe|...\n * Client → GET /resource with Authorization: Payment <base64url-json credential>\n * Server → 200 + Payment-Receipt: <base64url-json receipt>\n *\n * What we extract:\n * - Challenge: id, realm, method, intent, request{amount,currency,...}, expires, digest\n * - Credential: challenge + source (DID/chain-key) + payload (method-specific)\n * - Receipt: challengeId, method, reference (tx hash / pi_... ID), settlement\n * - Multi-method 402 offers (may be multiple WWW-Authenticate headers)\n *\n * What we do NOT verify here (pass-through):\n * - HMAC challenge binding (requires merchant's MPP_SECRET_KEY)\n * - Payment proof cryptography (Tempo tx sig, Stripe SPT, Lightning preimage)\n * — each requires upstream connectivity\n *\n * Verification (expiry + BodyDigest + source extraction) in mpp-verify.ts.\n */\n\nimport { Challenge, Credential, Receipt } from 'mppx';\n\nexport interface MPPChallengeSummary {\n id: string;\n realm: string;\n method: string;\n intent: string;\n /** Method-specific request data (amount, currency, recipient, etc.) */\n request: Record<string, unknown>;\n expires?: string;\n digest?: string;\n description?: string;\n opaque?: Record<string, string>;\n}\n\nexport interface MPPCredentialSummary {\n challenge: MPPChallengeSummary;\n /** DID or chain-native key identifying the payer. */\n source?: string;\n /** Method-specific payment proof (Tempo tx, SPT, Lightning preimage, etc.). */\n payload: unknown;\n}\n\nexport interface MPPReceiptSummary {\n method?: string;\n reference?: string;\n externalId?: string;\n status?: string;\n timestamp?: string;\n raw: Record<string, unknown>;\n}\n\nexport type MPPKind = 'challenge' | 'credential' | 'receipt' | 'error' | 'unknown';\n\nexport interface MPPRequestContext {\n kind: MPPKind;\n /** For 402 responses: one or more challenge offers. */\n challenges?: MPPChallengeSummary[];\n /** For requests with Authorization: Payment header. */\n credential?: MPPCredentialSummary;\n /** For 200 responses with Payment-Receipt header. */\n receipt?: MPPReceiptSummary;\n /** For problem+json error responses. */\n error?: { type?: string; title?: string; detail?: string };\n /** Detected payment methods offered (for multi-method 402). */\n offeredMethods?: string[];\n /** Raw body captured for BodyDigest verification in mpp-verify.ts. */\n rawBody?: string;\n}\n\nexport interface MPPRequestLike {\n method: string;\n url: string;\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n}\n\nexport interface MPPResponseLike {\n status: number;\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n}\n\n/**\n * Extract MPP context from an agent → merchant request.\n * Looks for `Authorization: Payment <credential>` header.\n */\nexport function extractMPPFromRequest(request: MPPRequestLike): MPPRequestContext | null {\n const auth = readHeader(request.headers, 'authorization');\n if (!auth || !/^\\s*Payment\\s+/i.test(auth)) return null;\n\n try {\n const credential = Credential.deserialize(auth);\n return {\n kind: 'credential',\n credential: {\n challenge: summarizeChallenge(credential.challenge),\n source: credential.source,\n payload: credential.payload,\n },\n rawBody: request.rawBody,\n };\n } catch {\n return { kind: 'error', error: { type: 'invalid-credential-encoding' } };\n }\n}\n\n/**\n * Extract MPP context from a merchant → agent response.\n * Handles 402 (challenge offers), 200 (receipt), 4xx (problem+json errors).\n */\nexport function extractMPPFromResponse(response: MPPResponseLike): MPPRequestContext | null {\n if (response.status === 402) {\n const challenges = collectChallenges(response);\n if (challenges.length === 0) return null;\n const methods = Array.from(new Set(challenges.map((c) => c.method)));\n return {\n kind: 'challenge',\n challenges,\n offeredMethods: methods,\n };\n }\n\n const receiptHeader = readHeader(response.headers, 'payment-receipt');\n if (receiptHeader) {\n try {\n const parsed = Receipt.deserialize(receiptHeader);\n const r = parsed as unknown as Record<string, unknown>;\n return {\n kind: 'receipt',\n receipt: {\n method: coerceString(r.method),\n reference: coerceString(r.reference),\n externalId: coerceString(r.externalId ?? r.external_id),\n status: coerceString(r.status),\n timestamp: coerceString(r.timestamp),\n raw: r,\n },\n };\n } catch {\n return { kind: 'error', error: { type: 'invalid-receipt-encoding' } };\n }\n }\n\n const contentType = readHeader(response.headers, 'content-type');\n if (contentType && /application\\/problem\\+json/i.test(contentType)) {\n const body =\n typeof response.body === 'object' && response.body !== null\n ? (response.body as Record<string, unknown>)\n : {};\n return {\n kind: 'error',\n error: {\n type: coerceString(body.type),\n title: coerceString(body.title),\n detail: coerceString(body.detail),\n },\n };\n }\n\n return null;\n}\n\n/**\n * Extract from either a request OR a response, auto-detecting which has MPP\n * artifacts. Convenience for pipeline callers.\n */\nexport function extractMPPContext(\n message:\n | { request: MPPRequestLike }\n | { response: MPPResponseLike }\n | (MPPRequestLike & Partial<MPPResponseLike>)\n): MPPRequestContext | null {\n if ('request' in message) return extractMPPFromRequest(message.request);\n if ('response' in message) return extractMPPFromResponse(message.response);\n if (typeof (message as MPPResponseLike).status === 'number') {\n return extractMPPFromResponse(message as MPPResponseLike);\n }\n return extractMPPFromRequest(message as MPPRequestLike);\n}\n\nfunction collectChallenges(response: MPPResponseLike): MPPChallengeSummary[] {\n const wwwAuth = readHeader(response.headers, 'www-authenticate');\n if (!wwwAuth) return [];\n const headers = new Headers();\n headers.set('www-authenticate', wwwAuth);\n\n const out: MPPChallengeSummary[] = [];\n try {\n const list = Challenge.fromHeadersList(headers);\n for (const ch of list) {\n out.push(summarizeChallenge(ch as unknown as Challenge.Challenge));\n }\n } catch {\n // fall through with empty list\n }\n return out;\n}\n\nfunction summarizeChallenge(\n ch: Challenge.Challenge | Record<string, unknown>\n): MPPChallengeSummary {\n const raw = ch as Record<string, unknown>;\n return {\n id: coerceString(raw.id) ?? '',\n realm: coerceString(raw.realm) ?? '',\n method: coerceString(raw.method) ?? '',\n intent: coerceString(raw.intent) ?? '',\n request: (raw.request as Record<string, unknown>) ?? {},\n expires: coerceString(raw.expires),\n digest: coerceString(raw.digest),\n description: coerceString(raw.description),\n opaque: raw.opaque as Record<string, string> | undefined,\n };\n}\n\nfunction readHeader(\n headers: Record<string, string | string[] | undefined>,\n name: string\n): string | undefined {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === name) {\n const raw = headers[key];\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw.join(', ');\n }\n }\n return undefined;\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n","/**\n * MPP verification — expiry + optional BodyDigest + source extraction.\n *\n * We do NOT verify the challenge's HMAC binding (needs merchant's secret)\n * or the cryptographic payment proof (per-method, requires upstream\n * connectivity). Those are the merchant's / settlement layer's job.\n *\n * Our job: structural correctness, expiry policy, tamper detection via\n * optional BodyDigest, and identity extraction for PDLSS binding.\n */\n\nimport { BodyDigest } from 'mppx';\nimport type { MPPRequestContext } from './mpp';\n\nexport interface MPPVerifyInput {\n context: MPPRequestContext;\n /** Raw request body to validate BodyDigest against, if the challenge declares one. */\n rawBody?: string;\n /** Seconds of clock-skew tolerance on challenge.expires. Default 300. */\n clockSkewSec?: number;\n /** Injectable for deterministic tests. */\n now?: () => number;\n}\n\nexport interface MPPVerifyResult {\n ok: boolean;\n expiryOk: boolean;\n bodyDigestOk: boolean | null;\n source?: string;\n method?: string;\n error?: string;\n}\n\nexport function verifyMPP(input: MPPVerifyInput): MPPVerifyResult {\n const { context } = input;\n const tolerance = input.clockSkewSec ?? 300;\n const nowSec = input.now ? input.now() : Math.floor(Date.now() / 1000);\n\n // Extract the challenge under test — for credential flow, from inside the\n // wrapped challenge; for bare challenge flow, from context.challenges[0].\n const challenge = context.credential?.challenge ?? (context.challenges && context.challenges[0]);\n const source = context.credential?.source;\n const method = challenge?.method;\n\n let expiryOk = true;\n if (challenge?.expires) {\n const parsedExpiry = Date.parse(challenge.expires);\n if (!Number.isFinite(parsedExpiry)) {\n return {\n ok: false,\n expiryOk: false,\n bodyDigestOk: null,\n source,\n method,\n error: 'unparseable challenge.expires',\n };\n }\n const expiresSec = Math.floor(parsedExpiry / 1000);\n if (nowSec > expiresSec + tolerance) {\n expiryOk = false;\n }\n }\n\n let bodyDigestOk: boolean | null = null;\n if (challenge?.digest && input.rawBody !== undefined) {\n try {\n if (!/^sha-256=/.test(challenge.digest)) {\n bodyDigestOk = false;\n } else {\n bodyDigestOk = BodyDigest.verify(challenge.digest as `sha-256=${string}`, input.rawBody);\n }\n } catch {\n bodyDigestOk = false;\n }\n }\n\n const ok = expiryOk && (bodyDigestOk === null || bodyDigestOk === true);\n const errors: string[] = [];\n if (!expiryOk) errors.push('challenge expired');\n if (bodyDigestOk === false) errors.push('body digest mismatch');\n\n return {\n ok,\n expiryOk,\n bodyDigestOk,\n source,\n method,\n error: errors.length > 0 ? errors.join('; ') : undefined,\n };\n}\n","/**\n * x402 (Coinbase / Linux Foundation x402 Foundation) extractor.\n *\n * Wraps @x402/core's schema parsers. x402 Foundation launched April 2 2026\n * with v2 adding network-agnostic identifiers + multiple facilitators +\n * Bazaar discovery. MPP (Machine Payments Protocol) is the IETF-formalised\n * superset of x402; this module normalizes x402 output to MPP-shape so\n * downstream pipeline code is uniform.\n *\n * Where x402 lives on the wire:\n * - 402 response body (v2) OR `X-PAYMENT-REQUIRED` header (v1) — PaymentRequired\n * - Request body (v2) OR `X-PAYMENT` header (v1, base64) — PaymentPayload\n */\n\nimport {\n validatePaymentRequired,\n validatePaymentPayload,\n type PaymentRequired,\n type PaymentPayload,\n type PaymentRequirements,\n} from '@x402/core/schemas';\nimport { safeBase64Decode } from '@x402/core/utils';\n\nexport type X402Kind = 'required' | 'payload' | 'error' | 'unknown';\n\nexport interface X402RequirementsSummary {\n scheme: string;\n network: string;\n asset: string;\n /** Normalized to string for v1/v2 compat — v1 uses maxAmountRequired, v2 uses amount. */\n amount: string;\n payTo: string;\n maxTimeoutSeconds?: number;\n resource?: string;\n description?: string;\n}\n\nexport interface X402RequestContext {\n kind: X402Kind;\n version: 1 | 2 | null;\n /** For 402 responses: the PaymentRequired body. */\n paymentRequired?: {\n resource: string;\n accepts: X402RequirementsSummary[];\n extensions?: Record<string, unknown>;\n error?: string;\n };\n /** For request body (v2) or X-PAYMENT header (v1 base64): the PaymentPayload. */\n paymentPayload?: {\n scheme: string;\n network: string;\n /** Free-form per-scheme payload (e.g. EIP-3009 authorization, Solana tx). */\n payload: Record<string, unknown>;\n extensions?: Record<string, unknown>;\n };\n error?: { type: string; detail?: string };\n /** Whether this was parsed from a header (v1 back-compat) or body (v2). */\n source: 'header' | 'body' | null;\n}\n\nexport interface X402RequestLike {\n method?: string;\n url?: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n}\n\nexport interface X402ResponseLike {\n status?: number;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n}\n\n/**\n * Extract x402 PaymentPayload from an agent → merchant request.\n * Checks v2 body (if it parses as PaymentPayload) and v1 X-PAYMENT header.\n */\nexport function extractX402FromRequest(request: X402RequestLike): X402RequestContext | null {\n const headerValue = readHeader(request.headers, 'x-payment');\n\n // v2 body path first\n if (request.body && typeof request.body === 'object') {\n const parsed = tryParsePayload(request.body);\n if (parsed) return buildPayloadContext(parsed, 'body');\n }\n\n // v1 header path\n if (headerValue) {\n try {\n const decoded = safeBase64Decode(headerValue);\n if (decoded) {\n const json = JSON.parse(decoded);\n const parsed = tryParsePayload(json);\n if (parsed) return buildPayloadContext(parsed, 'header');\n }\n } catch {\n return {\n kind: 'error',\n version: 1,\n source: 'header',\n error: { type: 'invalid-x402-payload' },\n };\n }\n }\n\n return null;\n}\n\n/**\n * Extract x402 PaymentRequired from a merchant → agent 402 response.\n */\nexport function extractX402FromResponse(response: X402ResponseLike): X402RequestContext | null {\n if (response.status !== 402) return null;\n\n // v2 body path\n if (response.body && typeof response.body === 'object') {\n const parsed = tryParseRequired(response.body);\n if (parsed) return buildRequiredContext(parsed, 'body');\n }\n\n // v1 header path\n const headerValue = readHeader(response.headers, 'x-payment-required');\n if (headerValue) {\n try {\n const decoded = safeBase64Decode(headerValue);\n if (decoded) {\n const json = JSON.parse(decoded);\n const parsed = tryParseRequired(json);\n if (parsed) return buildRequiredContext(parsed, 'header');\n }\n } catch {\n return {\n kind: 'error',\n version: 1,\n source: 'header',\n error: { type: 'invalid-x402-required' },\n };\n }\n }\n\n return null;\n}\n\nexport function extractX402Context(\n message:\n | { request: X402RequestLike }\n | { response: X402ResponseLike }\n | (X402RequestLike & Partial<X402ResponseLike>)\n): X402RequestContext | null {\n if ('request' in message) return extractX402FromRequest(message.request);\n if ('response' in message) return extractX402FromResponse(message.response);\n if (typeof (message as X402ResponseLike).status === 'number') {\n return extractX402FromResponse(message as X402ResponseLike);\n }\n return extractX402FromRequest(message as X402RequestLike);\n}\n\nfunction tryParseRequired(data: unknown): PaymentRequired | null {\n try {\n return validatePaymentRequired(data);\n } catch {\n return null;\n }\n}\n\nfunction tryParsePayload(data: unknown): PaymentPayload | null {\n try {\n return validatePaymentPayload(data);\n } catch {\n return null;\n }\n}\n\nfunction buildRequiredContext(\n parsed: PaymentRequired,\n source: 'header' | 'body'\n): X402RequestContext {\n const asRecord = parsed as unknown as Record<string, unknown>;\n const version = coerceVersion(asRecord.x402Version);\n const accepts = (asRecord.accepts as PaymentRequirements[] | undefined) ?? [];\n return {\n kind: 'required',\n version,\n source,\n paymentRequired: {\n resource: resolveResource(asRecord.resource),\n accepts: accepts.map(summarizeRequirement),\n extensions: asRecord.extensions as Record<string, unknown> | undefined,\n error: typeof asRecord.error === 'string' ? asRecord.error : undefined,\n },\n };\n}\n\nfunction buildPayloadContext(\n parsed: PaymentPayload,\n source: 'header' | 'body'\n): X402RequestContext {\n const asRecord = parsed as unknown as Record<string, unknown>;\n const version = coerceVersion(asRecord.x402Version);\n const accepted = asRecord.accepted as PaymentRequirements | undefined;\n const payload = (asRecord.payload as Record<string, unknown>) ?? {};\n return {\n kind: 'payload',\n version,\n source,\n paymentPayload: {\n scheme: accepted?.scheme ?? (typeof asRecord.scheme === 'string' ? asRecord.scheme : ''),\n network: accepted?.network ?? (typeof asRecord.network === 'string' ? asRecord.network : ''),\n payload,\n extensions: asRecord.extensions as Record<string, unknown> | undefined,\n },\n };\n}\n\nfunction summarizeRequirement(req: PaymentRequirements): X402RequirementsSummary {\n const r = req as unknown as Record<string, unknown>;\n const amount = (r.amount ?? r.maxAmountRequired ?? '0') as string;\n return {\n scheme: (r.scheme as string) ?? '',\n network: (r.network as string) ?? '',\n asset: (r.asset as string) ?? '',\n amount: String(amount),\n payTo: (r.payTo as string) ?? '',\n maxTimeoutSeconds: typeof r.maxTimeoutSeconds === 'number' ? r.maxTimeoutSeconds : undefined,\n resource: typeof r.resource === 'string' ? r.resource : undefined,\n description: typeof r.description === 'string' ? r.description : undefined,\n };\n}\n\nfunction resolveResource(v: unknown): string {\n if (typeof v === 'string') return v;\n if (v && typeof v === 'object' && 'url' in v && typeof (v as { url: unknown }).url === 'string') {\n return (v as { url: string }).url;\n }\n return '';\n}\n\nfunction coerceVersion(v: unknown): 1 | 2 | null {\n if (v === 1 || v === 2) return v;\n return null;\n}\n\nfunction readHeader(\n headers: Record<string, string | string[] | undefined> | undefined,\n name: string\n): string | undefined {\n if (!headers) return undefined;\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === name) {\n const raw = headers[key];\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw[0];\n }\n }\n return undefined;\n}\n","/**\n * VI (Verifiable Intent) 3-layer SD-JWT chain verification.\n *\n * VI chains: L1 (credential provider → wallet) → L2 (user → agent) → L3\n * (agent → merchant). L3 itself can split into L3a (payment mandate) + L3b\n * (checkout mandate) cross-referenced via transaction_id, with L3b carrying\n * a checkout_hash (VI constraint type 8) that must match SHA-256 of the L2\n * checkout disclosure.\n *\n * Signature primitives are delegated to @sd-jwt/core (via our extractor);\n * cnf.jwk chain-walking + cross-references + checkout_hash binding is\n * AstraSync-specific composition logic — that's the whitespace here.\n *\n * This module does NOT re-verify selective-disclosure hashes (the extractor\n * already applied them via @sd-jwt/decode). It DOES verify:\n * - cnf.jwk in L1 payload points to L2's signing key (thumbprint match)\n * - cnf.jwk in L2 payload points to L3's signing key\n * - L3a.transaction_id === L3b.transaction_id (when both present)\n * - L3b.checkout_hash === SHA-256(L2 canonical checkout disclosure) — type 8\n * - mandate-level `exp` is not in the past (beyond clock skew)\n *\n * Cryptographic signature verification on each layer uses the verifier\n * callback the caller supplies (e.g. resolves via @sd-jwt/core with the\n * right JWK from the L1 issuer's JWKS).\n */\n\nimport { createHash, webcrypto } from 'node:crypto';\nimport type { JWK } from 'jose';\n\nexport interface VILayer {\n /** Compact SD-JWT / JWS for this layer. */\n compact: string;\n /** Decoded JWT payload (already disclosure-merged). */\n payload: Record<string, unknown>;\n /** Decoded JWT header. */\n header: Record<string, unknown>;\n}\n\nexport interface VIVerifyInput {\n /**\n * Layers in chain order. L1 may be omitted when the caller has already\n * resolved the chain via a trusted wallet binding.\n */\n layers: {\n l1?: VILayer;\n l2: VILayer;\n l3a?: VILayer;\n l3b?: VILayer;\n };\n /**\n * Verifier callback invoked per layer. Should return true iff the layer's\n * JWS signature verifies against the resolved public key (for L2 this is\n * L1's cnf.jwk; for L3 this is L2's cnf.jwk; for L1 this is the issuer's\n * JWKS per `iss` claim).\n */\n verifySignature: (layer: VILayer, expectedKey: JWK | null) => Promise<boolean>;\n clockSkewSec?: number;\n now?: () => number;\n}\n\nexport interface VIVerifyResult {\n ok: boolean;\n checks: {\n l1SigOk: boolean | null;\n l2SigOk: boolean;\n l3aSigOk: boolean | null;\n l3bSigOk: boolean | null;\n l1BindsL2: boolean;\n l2BindsL3: boolean;\n l3aL3bTxnIdMatch: boolean | null;\n checkoutHashOk: boolean | null;\n expiryOk: boolean;\n };\n errors: string[];\n}\n\nexport async function verifyVIChain(input: VIVerifyInput): Promise<VIVerifyResult> {\n const errors: string[] = [];\n const tolerance = input.clockSkewSec ?? 300;\n const now = input.now ? input.now() : Math.floor(Date.now() / 1000);\n const { l1, l2, l3a, l3b } = input.layers;\n\n // Signature verification ---------------------------------\n const l1SigOk = l1 ? await input.verifySignature(l1, null) : null;\n if (l1 && !l1SigOk) errors.push('L1 signature invalid');\n\n const l1Cnf = extractCnfJwk(l1?.payload);\n const l2SigOk = await input.verifySignature(l2, l1Cnf ?? null);\n if (!l2SigOk) errors.push('L2 signature invalid');\n\n const l2Cnf = extractCnfJwk(l2.payload);\n const l3aSigOk = l3a ? await input.verifySignature(l3a, l2Cnf ?? null) : null;\n if (l3a && !l3aSigOk) errors.push('L3a signature invalid');\n const l3bSigOk = l3b ? await input.verifySignature(l3b, l2Cnf ?? null) : null;\n if (l3b && !l3bSigOk) errors.push('L3b signature invalid');\n\n // cnf.jwk binding ----------------------------------------\n let l1BindsL2 = true;\n if (l1Cnf) {\n const l2KeyFromHeader = await jwkForLayer(l2);\n l1BindsL2 = l2KeyFromHeader ? await thumbprintsMatch(l1Cnf, l2KeyFromHeader) : false;\n if (!l1BindsL2) errors.push('L1.cnf.jwk does not bind L2 signing key');\n }\n\n let l2BindsL3 = true;\n if (l2Cnf && (l3a || l3b)) {\n const l3Layer = l3a ?? l3b!;\n const l3KeyFromHeader = await jwkForLayer(l3Layer);\n l2BindsL3 = l3KeyFromHeader ? await thumbprintsMatch(l2Cnf, l3KeyFromHeader) : false;\n if (!l2BindsL3) errors.push('L2.cnf.jwk does not bind L3 signing key');\n }\n\n // L3a/L3b cross-reference --------------------------------\n let l3aL3bTxnIdMatch: boolean | null = null;\n if (l3a && l3b) {\n const a = coerceString(l3a.payload.transaction_id ?? l3a.payload.transactionId);\n const b = coerceString(l3b.payload.transaction_id ?? l3b.payload.transactionId);\n if (a && b) {\n l3aL3bTxnIdMatch = a === b;\n if (!l3aL3bTxnIdMatch) {\n errors.push(`L3a.transaction_id (${a}) does not match L3b.transaction_id (${b})`);\n }\n }\n }\n\n // checkout_hash (VI constraint type 8) -------------------\n let checkoutHashOk: boolean | null = null;\n if (l3b) {\n const declaredHash = coerceString(\n l3b.payload.checkout_hash ??\n l3b.payload.conditional_transaction_id ??\n (l3b.payload.payment_reference as Record<string, unknown> | undefined)?.checkout_hash\n );\n if (declaredHash) {\n const computed = computeCheckoutHashFromL2(l2);\n checkoutHashOk = computed ? declaredHash === computed : false;\n if (!checkoutHashOk) {\n errors.push('L3b.checkout_hash does not match SHA-256 of L2 checkout disclosure');\n }\n }\n }\n\n // Expiry policy ------------------------------------------\n const expiryOk = checkExpiryAcross([l1, l2, l3a, l3b], tolerance, now, errors);\n\n const ok =\n l1SigOk !== false &&\n l2SigOk &&\n l3aSigOk !== false &&\n l3bSigOk !== false &&\n l1BindsL2 &&\n l2BindsL3 &&\n l3aL3bTxnIdMatch !== false &&\n checkoutHashOk !== false &&\n expiryOk;\n\n return {\n ok,\n checks: {\n l1SigOk,\n l2SigOk,\n l3aSigOk,\n l3bSigOk,\n l1BindsL2,\n l2BindsL3,\n l3aL3bTxnIdMatch,\n checkoutHashOk,\n expiryOk,\n },\n errors,\n };\n}\n\nfunction extractCnfJwk(payload: Record<string, unknown> | undefined): JWK | null {\n if (!payload) return null;\n const cnf = payload.cnf as Record<string, unknown> | undefined;\n if (!cnf) return null;\n const jwk = cnf.jwk as JWK | undefined;\n return jwk ?? null;\n}\n\nasync function jwkForLayer(layer: VILayer): Promise<JWK | null> {\n // Prefer explicit cnf.jwk in the header, then payload; fallback to null.\n const fromHeader = extractCnfJwk(layer.header);\n if (fromHeader) return fromHeader;\n const fromPayload = extractCnfJwk(layer.payload);\n return fromPayload;\n}\n\nasync function thumbprintsMatch(a: JWK, b: JWK): Promise<boolean> {\n try {\n const ta = await jwkThumbprint(a);\n const tb = await jwkThumbprint(b);\n return ta === tb;\n } catch {\n return false;\n }\n}\n\n// RFC 7638 thumbprint: SHA-256 over the canonical JSON of required JWK members.\nasync function jwkThumbprint(jwk: JWK): Promise<string> {\n const canonical = canonicalJwk(jwk);\n const bytes = new TextEncoder().encode(JSON.stringify(canonical));\n const subtle = webcrypto.subtle as SubtleCrypto;\n const buffer = await new Promise<ArrayBuffer>((resolve, reject) => {\n const source = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(source).set(bytes);\n subtle.digest('SHA-256', source).then(resolve).catch(reject);\n });\n return Buffer.from(new Uint8Array(buffer)).toString('base64url').replace(/=+$/, '');\n}\n\nfunction canonicalJwk(jwk: JWK): Record<string, string> {\n // Per RFC 7638: members must appear in lexicographic order; only required\n // fields per kty are included.\n if (jwk.kty === 'EC') {\n return { crv: jwk.crv ?? '', kty: 'EC', x: jwk.x ?? '', y: jwk.y ?? '' };\n }\n if (jwk.kty === 'OKP') {\n return { crv: jwk.crv ?? '', kty: 'OKP', x: jwk.x ?? '' };\n }\n if (jwk.kty === 'RSA') {\n return { e: jwk.e ?? '', kty: 'RSA', n: jwk.n ?? '' };\n }\n return { kty: jwk.kty ?? '' };\n}\n\nfunction computeCheckoutHashFromL2(l2: VILayer): string | null {\n const checkoutDisclosure = (l2.payload.checkout ?? l2.payload.checkout_mandate) as unknown;\n if (!checkoutDisclosure) return null;\n const canonical = canonicalStringify(checkoutDisclosure);\n const hash = createHash('sha256').update(canonical).digest('base64url').replace(/=+$/, '');\n return hash;\n}\n\nfunction canonicalStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value);\n if (Array.isArray(value)) return '[' + value.map(canonicalStringify).join(',') + ']';\n const entries = Object.entries(value as Record<string, unknown>).sort(([a], [b]) =>\n a < b ? -1 : a > b ? 1 : 0\n );\n return (\n '{' + entries.map(([k, v]) => JSON.stringify(k) + ':' + canonicalStringify(v)).join(',') + '}'\n );\n}\n\nfunction checkExpiryAcross(\n layers: Array<VILayer | undefined>,\n toleranceSec: number,\n nowSec: number,\n errors: string[]\n): boolean {\n let ok = true;\n const names = ['L1', 'L2', 'L3a', 'L3b'];\n layers.forEach((layer, idx) => {\n if (!layer) return;\n const exp = toUnixSeconds(layer.payload.exp ?? layer.payload.expires);\n if (exp === undefined) return;\n if (nowSec > exp + toleranceSec) {\n errors.push(`${names[idx]} mandate expired at ${exp}`);\n ok = false;\n }\n });\n return ok;\n}\n\nfunction toUnixSeconds(v: unknown): number | undefined {\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (typeof v === 'string') {\n const asInt = Number(v);\n if (Number.isFinite(asInt) && asInt > 0) {\n return asInt >= 1e12 ? Math.floor(asInt / 1000) : Math.floor(asInt);\n }\n const parsed = Date.parse(v);\n if (Number.isFinite(parsed)) return Math.floor(parsed / 1000);\n }\n return undefined;\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n","/**\n * Commerce pipeline orchestrator.\n *\n * Ties together extractors + verifiers + identity binding + constraint\n * evaluation + trust signals into a single CommerceContext result.\n *\n * This is AstraSync whitespace: the orchestration over the library-backed\n * primitives. PR 3's Commerce Shield Lambda will call this per request;\n * the admin playground page will call it ad-hoc.\n *\n * Policy:\n * - Hard-deny (ok=false) on bad signatures, expired mandates, constraint\n * failures, identity cannot be bound.\n * - Trust signal (ok remains policy-driven) on ACP algorithm unsupported,\n * Stripe webhook HMAC fail, payment-token type unknown, cross-layer\n * identity mismatch.\n */\n\nimport type { ACPRequestContext } from './acp';\nimport { verifyACPSignature, type ACPVerifyResult } from './acp-verify';\nimport type { AP2MandateTriple } from './ap2';\nimport { verifyAP2Chain, type AP2ChainResult } from './ap2-verify';\nimport {\n evaluateVIConstraints,\n evaluatePaymentMethodAllowlist,\n evaluateSpendingLimit,\n type ConstraintEvalResult,\n type TransactionContext,\n} from './constraint-eval';\nimport { bindIdentity, type IdentityClaim, type IdentityResolver } from './identity-binding';\nimport { verifyMPP, type MPPVerifyResult } from './mpp-verify';\nimport type { MPPRequestContext } from './mpp';\nimport {\n mapACPRequestToPurpose,\n mapMPPRequestToPurpose,\n mapRFC9421TagToPurpose,\n mapUCPRequestToPurpose,\n mapVIMandateToPurpose,\n mapX402RequestToPurpose,\n type CommercePurpose,\n} from './purpose-mapping';\nimport {\n verifyRFC9421,\n type RFC9421VerifyResult,\n type RFC9421VerifyRequest,\n} from './rfc9421-verify';\nimport { verifyStripeWebhook, type VerifyStripeWebhookResult } from './stripe-webhook';\nimport {\n extractACPTransactionValue,\n extractMPPTransactionValue,\n extractUCPTransactionValue,\n extractVITransactionValue,\n extractX402TransactionValue,\n type TransactionValueContext,\n} from './transaction-value';\nimport type { UCPCheckoutContext } from './ucp';\nimport { verifyVIChain, type VIVerifyInput, type VIVerifyResult } from './vi-verify';\nimport type { VIExtractedClaims } from './vi';\nimport type { X402RequestContext } from './x402';\n\nexport type CommerceProtocol = 'vi' | 'ap2' | 'ucp' | 'acp' | 'agentpay' | 'tap' | 'mpp' | 'x402';\n\nexport interface CommercePipelineInput {\n protocol: CommerceProtocol;\n vi?: { claims: VIExtractedClaims; verifyInput?: VIVerifyInput };\n ap2?: { triple: AP2MandateTriple };\n ucp?: UCPCheckoutContext;\n acp?: {\n context: ACPRequestContext;\n verifyInput?: Parameters<typeof verifyACPSignature>[0];\n };\n rfc9421?: {\n request: RFC9421VerifyRequest;\n tag?: 'browse' | 'purchase' | string;\n verifyOptions: Parameters<typeof verifyRFC9421>[1];\n };\n mpp?: { context: MPPRequestContext; rawBody?: string };\n x402?: X402RequestContext;\n stripeWebhook?: { payload: string; signatureHeader: string; secret: string };\n transaction?: TransactionContext;\n registeredConstraints?: {\n allowedPaymentMethods?: string[];\n spendingLimit?: { amount?: number; currency?: string };\n };\n identityResolver?: IdentityResolver;\n clockSkewSec?: number;\n now?: () => number;\n}\n\nexport interface CommerceSignatureStack {\n vi?: VIVerifyResult;\n ap2?: AP2ChainResult;\n acp?: ACPVerifyResult;\n rfc9421?: RFC9421VerifyResult;\n mpp?: MPPVerifyResult;\n stripeWebhook?: VerifyStripeWebhookResult;\n}\n\nexport interface CommerceContext {\n protocol: CommerceProtocol;\n purpose: CommercePurpose | null;\n transactionValue?: TransactionValueContext;\n signatures: CommerceSignatureStack;\n identity?: {\n claims: IdentityClaim[];\n mappedAstraSyncAgentId?: string;\n mismatchAcrossLayers: boolean;\n };\n paymentToken?: {\n present: boolean;\n type: 'stripe-spt' | 'acp-vt' | 'tempo-tx' | 'other' | null;\n };\n mppMethodsOffered?: string[];\n constraints?: ConstraintEvalResult;\n receipt?: {\n method?: string;\n reference?: string;\n status?: string;\n timestamp?: string;\n };\n trustSignals: string[];\n timings: { extractMs: number; verifyMs: number; evalMs: number };\n /** False when any hard-deny rule fires. */\n ok: boolean;\n}\n\nexport async function runCommercePipeline(input: CommercePipelineInput): Promise<CommerceContext> {\n const trustSignals: string[] = [];\n const signatures: CommerceSignatureStack = {};\n const timings = { extractMs: 0, verifyMs: 0, evalMs: 0 };\n\n const extractStart = performance.now();\n const purpose = resolvePurpose(input);\n const transactionValue = resolveTransactionValue(input);\n const identityClaims = collectIdentityClaims(input);\n const paymentToken = resolvePaymentToken(input);\n timings.extractMs = Math.round(performance.now() - extractStart);\n\n const verifyStart = performance.now();\n let hardDeny = false;\n\n if (input.vi?.verifyInput) {\n signatures.vi = await verifyVIChain(input.vi.verifyInput);\n if (!signatures.vi.ok) hardDeny = true;\n }\n\n if (input.ap2) {\n signatures.ap2 = verifyAP2Chain({\n triple: input.ap2.triple,\n clockSkewSec: input.clockSkewSec,\n now: input.now,\n });\n if (!signatures.ap2.ok) hardDeny = true;\n }\n\n if (input.acp?.verifyInput) {\n signatures.acp = await verifyACPSignature(input.acp.verifyInput);\n if (!signatures.acp.ok && signatures.acp.timestampStale) hardDeny = true;\n if (signatures.acp.algorithm === 'unsupported') {\n trustSignals.push('acp-signature-algorithm-unsupported');\n } else if (!signatures.acp.ok) {\n hardDeny = true;\n }\n }\n\n if (input.rfc9421) {\n signatures.rfc9421 = await verifyRFC9421(input.rfc9421.request, input.rfc9421.verifyOptions);\n if (!signatures.rfc9421.ok) hardDeny = true;\n }\n\n if (input.mpp) {\n signatures.mpp = verifyMPP({\n context: input.mpp.context,\n rawBody: input.mpp.rawBody,\n clockSkewSec: input.clockSkewSec,\n now: input.now,\n });\n if (!signatures.mpp.ok) hardDeny = true;\n if (input.mpp.context.credential?.source) {\n trustSignals.push(`mpp-source-${shortSource(input.mpp.context.credential.source)}`);\n }\n }\n\n if (input.stripeWebhook) {\n signatures.stripeWebhook = verifyStripeWebhook(\n input.stripeWebhook.payload,\n input.stripeWebhook.signatureHeader,\n input.stripeWebhook.secret,\n { now: input.now ? () => input.now!() : undefined }\n );\n if (!signatures.stripeWebhook.ok) {\n trustSignals.push('stripe-webhook-hmac-failed');\n }\n }\n timings.verifyMs = Math.round(performance.now() - verifyStart);\n\n let identity: CommerceContext['identity'];\n if (input.identityResolver && identityClaims.length > 0) {\n const bound = await bindIdentity(identityClaims, input.identityResolver);\n identity = {\n claims: identityClaims,\n mappedAstraSyncAgentId: bound.mappedAstraSyncAgentId,\n mismatchAcrossLayers: bound.mismatchAcrossLayers,\n };\n if (bound.mismatchAcrossLayers) trustSignals.push('identity-mismatch-across-layers');\n } else if (identityClaims.length > 0) {\n identity = {\n claims: identityClaims,\n mappedAstraSyncAgentId: undefined,\n mismatchAcrossLayers: false,\n };\n }\n\n const evalStart = performance.now();\n const constraints = runConstraintEval(input);\n if (constraints && !constraints.ok) hardDeny = true;\n timings.evalMs = Math.round(performance.now() - evalStart);\n\n if (paymentToken?.type === 'stripe-spt') trustSignals.push('stripe-spt-present');\n if (paymentToken?.type === 'acp-vt') trustSignals.push('acp-vault-token-present');\n if (paymentToken?.type === 'tempo-tx') trustSignals.push('tempo-transaction-present');\n\n const mppReceipt = input.mpp?.context.receipt;\n\n return {\n protocol: input.protocol,\n purpose,\n transactionValue,\n signatures,\n identity,\n paymentToken,\n mppMethodsOffered: input.mpp?.context.offeredMethods,\n constraints,\n receipt: mppReceipt\n ? {\n method: mppReceipt.method,\n reference: mppReceipt.reference,\n status: mppReceipt.status,\n timestamp: mppReceipt.timestamp,\n }\n : undefined,\n trustSignals,\n timings,\n ok: !hardDeny,\n };\n}\n\nfunction resolvePurpose(input: CommercePipelineInput): CommercePurpose | null {\n if (input.vi?.claims.mandateType) {\n return mapVIMandateToPurpose(input.vi.claims.mandateType);\n }\n if (input.ap2?.triple.payment) return 'commerce.payment.execute';\n if (input.ap2?.triple.cart) return 'commerce.checkout.confirm';\n if (input.ap2?.triple.intent) return 'commerce.delegation.intent';\n if (input.ucp?.endpoint) {\n const [method, path] = input.ucp.endpoint.split(' ');\n return mapUCPRequestToPurpose(method ?? 'POST', path ?? '/');\n }\n if (input.acp?.context.endpoint) {\n // Extractor classifies as 'checkout_sessions.create|update|complete|cancel'\n // or 'delegate_payment'. Route each to the correct purpose.\n switch (input.acp.context.endpoint) {\n case 'checkout_sessions.create':\n return 'commerce.checkout.create';\n case 'checkout_sessions.update':\n return 'commerce.checkout.update';\n case 'checkout_sessions.complete':\n return 'commerce.payment.execute';\n case 'checkout_sessions.cancel':\n return 'commerce.checkout.cancel';\n case 'delegate_payment':\n return 'commerce.delegation.payment';\n default:\n return mapACPRequestToPurpose('POST', '/checkout_sessions');\n }\n }\n if (input.rfc9421?.tag) {\n return mapRFC9421TagToPurpose(\n input.rfc9421.tag === 'browse' || input.rfc9421.tag === 'purchase'\n ? (input.rfc9421.tag as 'browse' | 'purchase')\n : undefined\n );\n }\n if (input.mpp?.context.credential?.challenge || input.mpp?.context.challenges?.[0]) {\n const challenge = input.mpp.context.credential?.challenge ?? input.mpp.context.challenges?.[0];\n const amount = parseFloat(String(challenge?.request?.amount ?? 'NaN'));\n return mapMPPRequestToPurpose(\n challenge?.intent === 'session' ? 'session' : 'charge',\n Number.isFinite(amount) ? amount : undefined\n );\n }\n if (input.x402?.paymentRequired) {\n const amt = input.x402.paymentRequired.accepts[0]?.amount;\n return mapX402RequestToPurpose(Number(amt));\n }\n if (input.x402?.paymentPayload) return 'commerce.payment.execute';\n return null;\n}\n\nfunction resolveTransactionValue(\n input: CommercePipelineInput\n): TransactionValueContext | undefined {\n if (input.vi?.claims) {\n const v = extractVITransactionValue({\n constraints: input.vi.claims.constraints,\n l3aPaymentAmount: (input.vi.claims.constraints.paymentAmount &&\n typeof input.vi.claims.constraints.paymentAmount.max === 'number'\n ? {\n amount: input.vi.claims.constraints.paymentAmount.max,\n currency: input.vi.claims.constraints.paymentAmount.currency,\n }\n : undefined) as { amount?: number; currency?: string } | undefined,\n });\n if (v) return v;\n }\n if (input.ucp?.totals) {\n const v = extractUCPTransactionValue({ totals: input.ucp.totals });\n if (v) return v;\n }\n if (input.acp?.context.totals) {\n const v = extractACPTransactionValue({ totals: input.acp.context.totals });\n if (v) return v;\n }\n if (input.mpp?.context.credential?.challenge) {\n const ch = input.mpp.context.credential.challenge;\n const v = extractMPPTransactionValue({ method: ch.method, request: ch.request });\n if (v) return v;\n }\n if (input.x402?.paymentRequired) {\n const first = input.x402.paymentRequired.accepts[0];\n if (first) {\n const v = extractX402TransactionValue({\n maxAmountRequired: Number(first.amount),\n asset: first.asset,\n });\n if (v) return v;\n }\n }\n return undefined;\n}\n\nfunction collectIdentityClaims(input: CommercePipelineInput): IdentityClaim[] {\n const claims: IdentityClaim[] = [];\n if (input.vi?.claims.kid)\n claims.push({ protocol: 'vi', field: 'kid', value: input.vi.claims.kid });\n if (input.ap2?.triple) {\n const agentId =\n input.ap2.triple.intent?.agent_id ??\n input.ap2.triple.cart?.agent_id ??\n input.ap2.triple.payment?.agent_id;\n if (agentId) claims.push({ protocol: 'ap2', field: 'agent_id', value: agentId });\n }\n if (input.acp?.context.bearer) {\n claims.push({ protocol: 'acp', field: 'bearer', value: input.acp.context.bearer });\n }\n if (input.mpp?.context.credential?.source) {\n claims.push({ protocol: 'mpp', field: 'source', value: input.mpp.context.credential.source });\n }\n if (input.rfc9421) {\n // For RFC 9421 the kid is recorded after verify (result.kid); not collected here.\n }\n return claims;\n}\n\nfunction resolvePaymentToken(input: CommercePipelineInput): CommerceContext['paymentToken'] {\n if (input.acp?.context.paymentToken?.type) {\n return { present: true, type: input.acp.context.paymentToken.type };\n }\n const mppMethod = input.mpp?.context.credential?.challenge?.method;\n if (mppMethod === 'tempo') return { present: true, type: 'tempo-tx' };\n if (mppMethod === 'stripe') return { present: true, type: 'stripe-spt' };\n return undefined;\n}\n\nfunction runConstraintEval(input: CommercePipelineInput): ConstraintEvalResult | undefined {\n const transaction = input.transaction ?? {};\n const results: ConstraintEvalResult['results'] = {};\n const reasons: string[] = [];\n let hasAny = false;\n\n if (input.vi?.claims) {\n const viResult = evaluateVIConstraints({\n constraints: input.vi.claims.constraints,\n transaction,\n });\n for (const [k, v] of Object.entries(viResult.results)) {\n results[k] = v;\n if (!v.ok && v.reason) reasons.push(v.reason);\n }\n if (Object.keys(viResult.results).length > 0) hasAny = true;\n }\n\n const registered = input.registeredConstraints;\n if (registered?.allowedPaymentMethods) {\n const pm = evaluatePaymentMethodAllowlist({\n allowedMethods: registered.allowedPaymentMethods,\n requestedMethod: transaction.paymentMethod,\n });\n results.paymentMethod = pm;\n if (!pm.ok && pm.reason) reasons.push(pm.reason);\n hasAny = true;\n }\n if (registered?.spendingLimit) {\n const sp = evaluateSpendingLimit({\n limit: registered.spendingLimit,\n requested: { amount: transaction.amount, currency: transaction.currency },\n });\n results.spendingLimit = sp;\n if (!sp.ok && sp.reason) reasons.push(sp.reason);\n hasAny = true;\n }\n\n if (!hasAny) return undefined;\n return { ok: reasons.length === 0, results, reasons };\n}\n\nfunction shortSource(source: string): string {\n // Take first 16 chars sans scheme for trust-signal label readability.\n return source.replace(/^did:[a-z0-9]+:/, '').slice(0, 16);\n}\n","/**\n * Pluggable extractor registry for PR 3 Commerce Shield Lambda@Edge.\n *\n * Built-in extractors (VI, UCP, ACP, RFC 9421, MPP, x402, Stripe webhook)\n * are NOT auto-registered. PR 3 Lambda imports this module, picks the set\n * it wants, and calls registerTransportExtractor() for each.\n *\n * Re-registering by name replaces the prior extractor (idempotent).\n */\n\nexport interface ExtractorRequestLike {\n method?: string;\n url?: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n}\n\nexport interface TransportExtractor<T = unknown> {\n readonly name: string;\n match(request: ExtractorRequestLike): boolean;\n extract(request: ExtractorRequestLike): T | Promise<T> | null;\n}\n\nconst registry = new Map<string, TransportExtractor>();\n\nexport function registerTransportExtractor<T>(extractor: TransportExtractor<T>): void {\n if (!extractor || typeof extractor.name !== 'string' || extractor.name.length === 0) {\n throw new Error('registerTransportExtractor: extractor must have a non-empty name');\n }\n registry.set(extractor.name, extractor as TransportExtractor);\n}\n\nexport function getTransportExtractors(): ReadonlyArray<TransportExtractor> {\n return Array.from(registry.values());\n}\n\nexport function getTransportExtractor(name: string): TransportExtractor | undefined {\n return registry.get(name);\n}\n\nexport function clearTransportExtractors(): void {\n registry.clear();\n}\n\n/**\n * Helper: run all matching extractors against a request and return their\n * extracted contexts keyed by extractor name. Skips extractors whose\n * `match()` returns false.\n */\nexport async function runMatchingExtractors(\n request: ExtractorRequestLike\n): Promise<Record<string, unknown>> {\n const out: Record<string, unknown> = {};\n for (const extractor of registry.values()) {\n if (!extractor.match(request)) continue;\n const result = await extractor.extract(request);\n if (result !== null && result !== undefined) out[extractor.name] = result;\n }\n return out;\n}\n","/**\n * Visa JWKS registry resolver.\n *\n * Default endpoint: https://mcp.visa.com/.well-known/jwks (per Visa TAP spec).\n * Wraps jose.createRemoteJWKSet which handles caching + rotation natively.\n */\n\nimport { createRemoteJWKSet, type JWK } from 'jose';\nimport type { RegistryResolver, ResolveContext } from './types';\n\nconst DEFAULT_VISA_JWKS_URL = 'https://mcp.visa.com/.well-known/jwks';\n\nexport interface VisaRegistryOptions {\n jwksUrl?: string;\n cacheMaxAge?: number;\n cooldownDuration?: number;\n}\n\nexport function createVisaRegistry(options: VisaRegistryOptions = {}): RegistryResolver {\n const url = new URL(options.jwksUrl ?? DEFAULT_VISA_JWKS_URL);\n const jwks = createRemoteJWKSet(url, {\n cacheMaxAge: options.cacheMaxAge,\n cooldownDuration: options.cooldownDuration,\n });\n\n return {\n name: 'visa',\n async resolve(kid: string, context?: ResolveContext): Promise<JWK | null> {\n if (!kid) return null;\n try {\n const key = await jwks({\n kid,\n alg: context?.algorithm ?? 'ES256',\n typ: 'JWT',\n });\n return exportJwkFromKeyLike(key);\n } catch {\n return null;\n }\n },\n };\n}\n\nasync function exportJwkFromKeyLike(keyLike: unknown): Promise<JWK | null> {\n if (!keyLike) return null;\n // jose returns KeyObject or CryptoKey — both export via exportJWK at caller side.\n // Runtime shape check: if it already looks like a JWK, pass through.\n if (typeof keyLike === 'object' && 'kty' in (keyLike as object)) {\n return keyLike as JWK;\n }\n const { exportJWK } = await import('jose');\n try {\n return await exportJWK(keyLike as Parameters<typeof exportJWK>[0]);\n } catch {\n return null;\n }\n}\n","/**\n * Mastercard Agent Registry resolver — STUB.\n *\n * Mastercard Agent Pay is behind partnership (pilots Feb 2026, GA Q2 2026).\n * No public Agent Registry URL or open-source resolver exists as of April\n * 2026. This resolver accepts an optional `registryUrl` and, when absent,\n * returns null with a single one-time console.warn so callers can plumb\n * the flow end-to-end without a live registry.\n *\n * When Mastercard ships a public resolver or when a commercial relationship\n * provides a registry URL, pass it via `MastercardRegistryOptions.registryUrl`.\n * Response shape expected: { keys: JWK[] } (JWKS-style).\n */\n\nimport type { JWK } from 'jose';\nimport type { RegistryResolver } from './types';\n\nexport interface MastercardRegistryOptions {\n /** Partnership-provided registry URL. Without it, the resolver is inert. */\n registryUrl?: string;\n /** Cache TTL in seconds. Default 3600. */\n cacheTtlSec?: number;\n /** Fetch fn override for testing. */\n fetch?: typeof fetch;\n /** Silence the one-time warn (testing only). */\n silent?: boolean;\n}\n\ninterface CachedKey {\n jwk: JWK;\n expiresAt: number;\n}\n\nexport function createMastercardRegistry(\n options: MastercardRegistryOptions = {}\n): RegistryResolver {\n const cache = new Map<string, CachedKey>();\n const ttlSec = options.cacheTtlSec ?? 3600;\n const fetchFn = options.fetch ?? globalThis.fetch;\n let warned = false;\n\n return {\n name: 'mastercard',\n async resolve(kid: string): Promise<JWK | null> {\n if (!kid) return null;\n\n if (!options.registryUrl) {\n if (!warned && !options.silent) {\n warned = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[mastercard-registry] registryUrl not configured — key resolution disabled. ' +\n 'Kid lookups will return null until a partnership registry is supplied.'\n );\n }\n return null;\n }\n\n const cached = cache.get(kid);\n if (cached && cached.expiresAt > Date.now()) return cached.jwk;\n\n try {\n const res = await fetchFn(options.registryUrl);\n if (!res.ok) return null;\n const body = (await res.json()) as { keys?: JWK[] };\n const keys = body.keys ?? [];\n for (const k of keys) {\n if (k.kid === kid) {\n cache.set(kid, { jwk: k, expiresAt: Date.now() + ttlSec * 1000 });\n return k;\n }\n }\n return null;\n } catch {\n return null;\n }\n },\n };\n}\n","/**\n * Web Bot Auth registry resolver.\n *\n * IETF draft-meunier-web-bot-auth-architecture-05 + draft-meunier-http-\n * message-signatures-directory-01. Shared transport substrate under TAP,\n * Agent Pay, and Cloudflare Pay Per Crawl.\n *\n * Fetches a Web Bot Auth signature directory\n * (default: `<origin>/.well-known/http-message-signatures-directory`).\n * Shape per spec is a JWKS with Ed25519 keys.\n *\n * Wraps Cloudflare's `web-bot-auth` npm package where feasible; for raw\n * directory fetch + kid matching we use fetch + JSON since web-bot-auth's\n * higher-level API assumes a full request to verify.\n */\n\nimport type { JWK } from 'jose';\nimport type { RegistryResolver, ResolveContext } from './types';\n\nconst DIRECTORY_PATH = '/.well-known/http-message-signatures-directory';\n\nexport interface WebBotAuthRegistryOptions {\n /**\n * Optional explicit directory URL. When omitted, the resolver derives one\n * from `ResolveContext.origin` (e.g. the request URL's origin at verify time).\n */\n directoryUrl?: string;\n cacheTtlSec?: number;\n fetch?: typeof fetch;\n}\n\ninterface DirectoryCache {\n keys: JWK[];\n expiresAt: number;\n}\n\nexport function createWebBotAuthRegistry(\n options: WebBotAuthRegistryOptions = {}\n): RegistryResolver {\n const cache = new Map<string, DirectoryCache>();\n const ttlSec = options.cacheTtlSec ?? 3600;\n const fetchFn = options.fetch ?? globalThis.fetch;\n\n return {\n name: 'web-bot-auth',\n async resolve(kid: string, context?: ResolveContext): Promise<JWK | null> {\n if (!kid) return null;\n\n const directoryUrl = resolveDirectoryUrl(options.directoryUrl, context?.origin);\n if (!directoryUrl) return null;\n\n const cached = cache.get(directoryUrl);\n const now = Date.now();\n if (cached && cached.expiresAt > now) {\n return findKeyByKid(cached.keys, kid);\n }\n\n try {\n const res = await fetchFn(directoryUrl);\n if (!res.ok) return null;\n const body = (await res.json()) as { keys?: JWK[] };\n const keys = body.keys ?? [];\n cache.set(directoryUrl, { keys, expiresAt: now + ttlSec * 1000 });\n return findKeyByKid(keys, kid);\n } catch {\n return null;\n }\n },\n };\n}\n\nfunction resolveDirectoryUrl(\n explicit: string | undefined,\n origin: string | undefined\n): string | null {\n if (explicit) return explicit;\n if (!origin) return null;\n try {\n const url = new URL(origin);\n return `${url.origin}${DIRECTORY_PATH}`;\n } catch {\n return null;\n }\n}\n\nfunction findKeyByKid(keys: JWK[], kid: string): JWK | null {\n for (const k of keys) {\n if (k.kid === kid) return k;\n }\n return null;\n}\n","/**\n * MCP server-side helpers — companion to `transport/mcp.ts` (which handles the\n * agent-side `_meta.astrasync` block).\n *\n * Surfaces a body-aware policy hook the existing `createMiddleware` couldn't\n * provide — MCP traffic is JSON-RPC over a single endpoint (`/mcp`), so the\n * default route-pattern gating is too coarse: every request looks the same\n * URL-wise, but `initialize` is low-risk handshake while `tools/call` of a\n * payment tool is high-risk. Cohort-3 beta merchants flagged this 🟡 in the\n * v2.9.5 round.\n *\n * What lives here:\n * - `parseMcpJsonRpc(body)` — peels JSON-RPC method + tool name + agent\n * id without committing to a particular MCP\n * server framework.\n * - `mcpToPdlss(parsed)` — canonical mapping JSON-RPC method → PDLSS\n * purpose / action / resource. Doc-stable\n * so audits can correlate.\n * - `mcpRiskTier(parsed)` — recommended `minAccessLevel` per method\n * so a single MCP middleware can split\n * `initialize` / `tools/list` (low gate)\n * from `tools/call` (high gate).\n * - `MCP_VERIFIED_HOP_HEADER` — header convention for the dedupe pattern\n * when an MCP tool calls an inner REST hop.\n * - `serialize/parseVerifiedHop` helpers.\n *\n * The Express MCP adapter is in `adapters/mcp.ts` and consumes these.\n */\n\nimport type { AccessLevel } from '../types';\n\n/**\n * Header carrying upstream verify-access proof so an inner-hop REST endpoint\n * can dedupe (skip verify-access when the same ASTRA-id was already verified\n * a few ms earlier). Value format:\n *\n * {astraId};{sessionId};{checkedAt-ms}\n *\n * Receivers MUST validate that `checkedAt` is recent (≤ 60s window\n * recommended) and that `astraId` matches the agent identity claimed on the\n * inner hop. The header alone is NOT proof-of-identity — it's a dedupe\n * advisory. Pair with the existing X-Astra-Id auth.\n */\nexport const MCP_VERIFIED_HOP_HEADER = 'X-Astra-Verified-Hop';\n\n/** Default acceptable age (ms) for an X-Astra-Verified-Hop header. */\nexport const MCP_VERIFIED_HOP_MAX_AGE_MS = 60_000;\n\nexport interface VerifiedHopMarker {\n astraId: string;\n sessionId?: string;\n checkedAt: number; // epoch ms\n}\n\nexport function serializeVerifiedHop(marker: VerifiedHopMarker): string {\n return `${marker.astraId};${marker.sessionId ?? ''};${marker.checkedAt}`;\n}\n\nexport function parseVerifiedHop(value: string | undefined | null): VerifiedHopMarker | null {\n if (!value) return null;\n const parts = value.split(';');\n if (parts.length !== 3) return null;\n const [astraId, sessionId, checkedAtRaw] = parts;\n if (!astraId) return null;\n const checkedAt = Number(checkedAtRaw);\n if (!Number.isFinite(checkedAt) || checkedAt <= 0) return null;\n return {\n astraId,\n ...(sessionId ? { sessionId } : {}),\n checkedAt,\n };\n}\n\n/**\n * Returns true when `marker.astraId` matches the inner-hop's claimed\n * ASTRA-id AND the marker is recent enough. Inner-hop middleware uses this\n * to skip a duplicate verify-access call.\n */\nexport function isVerifiedHopValidFor(\n marker: VerifiedHopMarker | null,\n expectedAstraId: string,\n opts: { maxAgeMs?: number; now?: number } = {}\n): boolean {\n if (!marker) return false;\n if (marker.astraId !== expectedAstraId) return false;\n const maxAge = opts.maxAgeMs ?? MCP_VERIFIED_HOP_MAX_AGE_MS;\n const now = opts.now ?? Date.now();\n return now - marker.checkedAt <= maxAge && now >= marker.checkedAt;\n}\n\n/**\n * Output of `parseMcpJsonRpc`. Self-describing so the middleware doesn't have\n * to re-introspect the body to figure out gating.\n */\nexport interface ParsedMcpRequest {\n /** JSON-RPC method (e.g. `tools/call`, `initialize`, `tools/list`). */\n method: string;\n /** Set when method === 'tools/call'; the tool name from `params.name`. */\n toolName?: string;\n /** Initialize-specific protocolVersion handshake info, when present. */\n protocolVersion?: string;\n /**\n * Agent id read from the body, in priority order:\n * 1. `params._meta.astrasync.agentId` (the canonical SDK location, see\n * `transport/mcp.ts → setMcpMeta`)\n * 2. `params.arguments.agent_id` (legacy / hand-written tool callers)\n * Header-supplied id (X-Astra-Id) is read separately by the adapter and\n * compared to this for the mismatch check.\n */\n agentIdFromBody?: string;\n /**\n * Round-12 (F19) + round-13 (R13-1): purpose extracted from the MCP body\n * with the symmetric precedence chain. Sourced from `_meta.astrasync.purpose`\n * (canonical SDK location) OR `params.arguments.purpose` (legacy /\n * conventional callers). The discriminator is on `purposeSourceFromBody`.\n * Adapter combines this with the `X-Astra-Purpose` header (header wins)\n * before mapping; final fallback at `mcpToPdlss` is `'mcp_invoke'`.\n */\n purposeFromBody?: string;\n /** Which body location resolved `purposeFromBody`. */\n purposeSourceFromBody?: 'meta' | 'tool_argument';\n /**\n * Round-13 (R13-2): action extracted from the MCP body with the same\n * symmetric chain as purpose. Sourced from `_meta.astrasync.action`\n * (canonical) OR `params.arguments.action` (legacy). Adapter combines\n * with the `X-Astra-Action` header (header wins) before mapping; final\n * fallback at `mcpToPdlss` is the transport-layer default\n * (`tools/call:<toolname>` or just `<method>`).\n */\n actionFromBody?: string;\n /** Which body location resolved `actionFromBody`. */\n actionSourceFromBody?: 'meta' | 'tool_argument';\n /** True for handshake methods that must succeed before any tool call. */\n isInitialize: boolean;\n /** True for `tools/call`. */\n isToolCall: boolean;\n /** True for low-risk introspection (`tools/list`, `prompts/list`, etc.). */\n isIntrospection: boolean;\n}\n\n/**\n * Peel the JSON-RPC envelope. Returns `null` if the body isn't a JSON-RPC\n * request (callers can short-circuit with a 400 or treat as untyped traffic).\n *\n * Accepts both single-request and notification shapes. Batch requests are\n * NOT supported here — the verify-access contract is single-agent-per-call;\n * a batch body should be split before policy gating.\n */\nexport function parseMcpJsonRpc(body: unknown): ParsedMcpRequest | null {\n if (!body || typeof body !== 'object' || Array.isArray(body)) return null;\n const obj = body as Record<string, unknown>;\n if (obj.jsonrpc !== '2.0' && obj.jsonrpc !== '1.0') return null;\n const method = typeof obj.method === 'string' ? obj.method : null;\n if (!method) return null;\n const params = obj.params as Record<string, unknown> | undefined;\n\n // Tool-name lookup. MCP `tools/call` puts the tool under `params.name`.\n let toolName: string | undefined;\n if (method === 'tools/call' && params && typeof params.name === 'string') {\n toolName = params.name;\n }\n\n // protocolVersion only on the initialize request.\n let protocolVersion: string | undefined;\n if (method === 'initialize' && params && typeof params.protocolVersion === 'string') {\n protocolVersion = params.protocolVersion;\n }\n\n const meta = params?._meta as Record<string, unknown> | undefined;\n const astrasyncMeta = meta?.astrasync as Record<string, unknown> | undefined;\n const args = params?.arguments as Record<string, unknown> | undefined;\n\n // Agent-id lookup with documented precedence: _meta.astrasync.agentId\n // wins over params.arguments.agent_id. (The argument-shape uses\n // `agent_id` snake_case for legacy conventional callers; meta is the\n // canonical SDK location.)\n let agentIdFromBody: string | undefined;\n if (astrasyncMeta && typeof astrasyncMeta.agentId === 'string') {\n agentIdFromBody = astrasyncMeta.agentId;\n } else if (args && typeof args.agent_id === 'string') {\n agentIdFromBody = args.agent_id;\n }\n\n // Round-13 (R13-1, R13-2) — symmetric body-extraction for purpose +\n // action. Per `feedback_symmetric_fallbacks_for_symmetric_concepts.md`:\n // these two concepts are paired in the MCP middleware, so their\n // fallback chains MUST mirror each other exactly. Drift between them\n // generates the same support-ticket class repeatedly (\"I set X in\n // arguments and it didn't take\" — happened for purpose in round-12\n // post-F19, and was about to happen for action in round-13).\n //\n // Body precedence (applies to both): _meta.astrasync.<key> wins over\n // params.arguments.<key>. The discriminator is exported alongside the\n // value so the adapter can fold it into purposeSource / actionSource\n // for debug logging and adoption tracking.\n const purposeBodyResult = extractFromMcpBody(astrasyncMeta, args, 'purpose');\n const actionBodyResult = extractFromMcpBody(astrasyncMeta, args, 'action');\n\n const isInitialize = method === 'initialize';\n const isToolCall = method === 'tools/call';\n const isIntrospection =\n method === 'tools/list' ||\n method === 'prompts/list' ||\n method === 'resources/list' ||\n method === 'ping' ||\n method === 'notifications/initialized';\n\n return {\n method,\n ...(toolName ? { toolName } : {}),\n ...(protocolVersion ? { protocolVersion } : {}),\n ...(agentIdFromBody ? { agentIdFromBody } : {}),\n ...(purposeBodyResult.value ? { purposeFromBody: purposeBodyResult.value } : {}),\n ...(purposeBodyResult.source ? { purposeSourceFromBody: purposeBodyResult.source } : {}),\n ...(actionBodyResult.value ? { actionFromBody: actionBodyResult.value } : {}),\n ...(actionBodyResult.source ? { actionSourceFromBody: actionBodyResult.source } : {}),\n isInitialize,\n isToolCall,\n isIntrospection,\n };\n}\n\n/**\n * Shared body-extraction helper for the symmetric purpose + action\n * fallback chain (round-13 R13-1, R13-2). Returns the resolved value AND\n * the source discriminator so adapters can fold it into per-call debug\n * logs (`purpose_source` / `action_source`).\n *\n * Precedence:\n * 1. `params._meta.astrasync.<key>` — canonical SDK location, source: 'meta'\n * 2. `params.arguments.<key>` — legacy / conventional, source: 'tool_argument'\n * 3. neither present — value: undefined, source: undefined\n *\n * The HTTP-header tier (`X-Astra-<concept>`) is the adapter's job; this\n * helper only handles body sources. Adapters combine the two: header\n * wins over body. See `mcpToPdlss` for the final precedence assembly.\n */\nfunction extractFromMcpBody(\n astrasyncMeta: Record<string, unknown> | undefined,\n args: Record<string, unknown> | undefined,\n key: 'purpose' | 'action'\n): { value: string | undefined; source: 'meta' | 'tool_argument' | undefined } {\n if (astrasyncMeta && typeof astrasyncMeta[key] === 'string') {\n return { value: astrasyncMeta[key] as string, source: 'meta' };\n }\n if (args && typeof args[key] === 'string') {\n return { value: args[key] as string, source: 'tool_argument' };\n }\n return { value: undefined, source: undefined };\n}\n\n/**\n * PDLSS mapping for an MCP request. The platform's PDLSS taxonomy is\n * `purpose / action / resource`; for MCP traffic the audit-useful dimensions\n * are the JSON-RPC method and (for `tools/call`) the tool name. Doc-stable so\n * dashboards and audits can correlate consistently across cohort-3 partners.\n *\n * Rules:\n * - `purpose` is always `mcp_invoke` for MCP traffic — sets the high-level\n * PDLSS bucket.\n * - `action` is the JSON-RPC method, optionally `:tool_name` suffixed for\n * `tools/call`. Lets PDLSS allowlist specific tools.\n * - `resource` is `mcp:tool/<name>` for `tools/call`, `mcp:method/<method>`\n * otherwise. Lets PDLSS scope on tool identity.\n */\nexport interface McpPdlssMapping {\n purpose: string;\n action: string;\n resource: string;\n /**\n * Round-13 (R13-1 / R13-2): the resolution channel for purpose and\n * action — disjoint enums sharing the same structure per\n * `feedback_symmetric_fallbacks_for_symmetric_concepts.md`. Adapters\n * log both at debug level so partners can confirm header / body\n * pass-through, support can triage tickets, and we can watch the\n * `default_*` / `transport_layer` decay over time as integrations\n * mature.\n *\n * Round-12 (F19) used a narrower `purposeSource: 'header' |\n * 'tool_argument' | 'default_mcp_invoke'` — round-13 widens to also\n * carry the `_meta` source distinct from `tool_argument`, so the round-13\n * R13-1 fallback (which now reads both `_meta.astrasync.purpose` AND\n * `params.arguments.purpose`) can report WHICH body location resolved.\n */\n purposeSource: 'header' | 'meta' | 'tool_argument' | 'default_mcp_invoke';\n actionSource: 'header' | 'meta' | 'tool_argument' | 'transport_layer';\n}\n\n/**\n * Round-13 (R13-1 + R13-2) — canonical precedence chain documented ONCE,\n * applied identically to both purpose and action. Per\n * `feedback_symmetric_fallbacks_for_symmetric_concepts.md` — drift\n * between two paired concepts generates the same support-ticket class\n * repeatedly, so the resolution order is:\n *\n * 1. `X-Astra-<concept>` HTTP header (caller's explicit override)\n * 2. `params._meta.astrasync.<concept>` body field (canonical SDK location)\n * 3. `params.arguments.<concept>` body field (legacy / conventional)\n * 4. Transport-layer default:\n * purpose → 'mcp_invoke'\n * action → '<method>:<toolName>' (or just '<method>')\n *\n * The header tier is the adapter's job (it has `req.headers` access);\n * this function takes the resolved `headerPurpose` / `headerAction`\n * inputs and combines them with the body extraction already done in\n * `parseMcpJsonRpc`. The discriminator is reported on `purposeSource` /\n * `actionSource` for debug logging.\n */\nexport function mcpToPdlss(\n parsed: ParsedMcpRequest,\n headerPurpose?: string,\n headerAction?: string\n): McpPdlssMapping {\n const resource = parsed.toolName ? `mcp:tool/${parsed.toolName}` : `mcp:method/${parsed.method}`;\n\n // Purpose resolution: header > body (_meta, then tool_argument) > default\n let purpose: string;\n let purposeSource: McpPdlssMapping['purposeSource'];\n if (headerPurpose) {\n purpose = headerPurpose;\n purposeSource = 'header';\n } else if (parsed.purposeFromBody && parsed.purposeSourceFromBody) {\n purpose = parsed.purposeFromBody;\n purposeSource = parsed.purposeSourceFromBody;\n } else {\n purpose = 'mcp_invoke';\n purposeSource = 'default_mcp_invoke';\n }\n\n // Action resolution: identical chain, transport-layer default differs\n let action: string;\n let actionSource: McpPdlssMapping['actionSource'];\n if (headerAction) {\n action = headerAction;\n actionSource = 'header';\n } else if (parsed.actionFromBody && parsed.actionSourceFromBody) {\n action = parsed.actionFromBody;\n actionSource = parsed.actionSourceFromBody;\n } else {\n action = parsed.toolName ? `${parsed.method}:${parsed.toolName}` : parsed.method;\n actionSource = 'transport_layer';\n }\n\n return { purpose, action, resource, purposeSource, actionSource };\n}\n\n/**\n * Recommended minimum access level per method type. The MCP middleware uses\n * this to split low-risk handshake / introspection traffic from high-risk\n * tool execution — defect (a) from the cohort-3 review.\n *\n * - `initialize` / `notifications/initialized` → `none` (handshake must work for unregistered probes)\n * - `tools/list` / `prompts/list` / `resources/list` → `none` (introspection is public-surface)\n * - `ping` → `none`\n * - `resources/read` → `read-only`\n * - `tools/call` → `standard` (default — overridable per-tool)\n * - everything else → `standard` (least-privilege fallback)\n */\nexport function mcpRiskTier(parsed: ParsedMcpRequest): AccessLevel {\n if (parsed.isInitialize || parsed.method === 'notifications/initialized') return 'none';\n if (parsed.isIntrospection) return 'none';\n if (parsed.method === 'resources/read') return 'read-only';\n if (parsed.isToolCall) return 'standard';\n return 'standard';\n}\n","/**\n * AstraSync Universal Verification Gateway — MCP middleware\n *\n * Express-shaped middleware tailored to the JSON-RPC body of an MCP\n * (Model Context Protocol) endpoint. Closes the cohort-3 gaps the default\n * `createMiddleware` couldn't:\n *\n * (a) **Body-aware gating**. All MCP traffic targets the same `/mcp` URL.\n * The default route-pattern matcher can't tell `initialize` (low risk)\n * from `tools/call start_checkout` (high risk). This middleware peels\n * the JSON-RPC body and applies a per-method risk tier.\n *\n * (b) **PDLSS mapping**. Forwards `purpose=mcp_invoke`,\n * `action=method[:tool]`, `resource=mcp:tool/<name>` so audit traces\n * are stable across cohort-3 partners. See `transport/mcp-server.ts`\n * for the exact mapping.\n *\n * (c) **Inner-hop dedupe**. Outbound responses set\n * `X-Astra-Verified-Hop` so a downstream REST endpoint that the tool\n * calls can skip a duplicate verify-access. The receiving REST\n * middleware checks `parseVerifiedHop` and skips when valid.\n *\n * (d) **Header-vs-body identity precedence**. Reads ASTRA-id from\n * `X-Astra-Id` first, body second. If both are present and disagree,\n * returns a structured 400 by default (configurable). Pre-fix,\n * integrators had to re-discover this on their own.\n *\n * Usage:\n *\n * ```typescript\n * import express from 'express';\n * import { createMcpMiddleware } from '@astrasyncai/verification-gateway/mcp';\n *\n * const app = express();\n * app.use(express.json());\n *\n * app.post(\n * '/mcp',\n * createMcpMiddleware({\n * apiBaseUrl: 'https://astrasync.ai/api',\n * apiKey: process.env.ASTRASYNC_API_KEY,\n * // Optional per-tool overrides — tools not listed get the default tier\n * // from `mcpRiskTier` (`tools/call` → 'standard').\n * toolGates: {\n * start_checkout: 'standard',\n * confirm_purchase: 'full',\n * browse_catalog: 'read-only',\n * },\n * }),\n * yourMcpServerHandler,\n * );\n * ```\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type {\n GatewayConfig,\n AccessLevel,\n VerificationResult,\n EnhancedVerificationResult,\n} from '../types';\nimport {\n verify,\n extractCredentials,\n recordDecision,\n recordAnonymousLocalOverride,\n} from '../verify';\nimport { hasMinimumAccess } from '../access-levels';\nimport {\n parseMcpJsonRpc,\n mcpToPdlss,\n mcpRiskTier,\n serializeVerifiedHop,\n parseVerifiedHop,\n isVerifiedHopValidFor,\n MCP_VERIFIED_HOP_HEADER,\n type ParsedMcpRequest,\n} from '../transport/mcp-server';\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Express {\n interface Request {\n mcpRequest?: ParsedMcpRequest;\n }\n }\n}\n\nexport interface McpMiddlewareOptions extends GatewayConfig {\n /**\n * Per-tool override for the minimum access level. Tools not listed inherit\n * the default tier from `mcpRiskTier` (`tools/call` → `'standard'`). Use\n * for high-risk tools that demand `'full'` or low-risk read-only tools.\n */\n toolGates?: Record<string, AccessLevel>;\n /**\n * Per-method override (e.g. tighten `tools/list` to `'read-only'` if you\n * don't want unregistered probes seeing your tool catalogue). Matches by\n * exact JSON-RPC method string.\n */\n methodGates?: Record<string, AccessLevel>;\n /**\n * What to do when the agent id supplied in the X-Astra-Id header\n * disagrees with the agent id in the JSON-RPC body\n * (`params._meta.astrasync.agentId` or `params.arguments.agent_id`).\n *\n * - `'reject'` (default) — return 400 `AGENT_ID_MISMATCH`. Safest.\n * - `'prefer-header'` — log + verify against the header value. Keeps\n * bodies that were authored before X-Astra-Id was the canonical\n * identity slot working.\n * - `'prefer-body'` — log + verify against the body value. Useful in\n * reverse-proxy setups that strip auth headers.\n */\n onAgentIdMismatch?: 'reject' | 'prefer-header' | 'prefer-body';\n /** Skip verification + dedupe entirely. For testing. */\n skip?: boolean;\n /** Custom denied handler. Defaults to a structured JSON-RPC error response. */\n onDenied?: (result: VerificationResult, req: Request, res: Response) => void;\n /**\n * If `false`, don't trust an inbound `X-Astra-Verified-Hop` header (always\n * call verify-access). Default `true` — recommended for inner-hop endpoints\n * called by your own MCP tools.\n */\n trustVerifiedHop?: boolean;\n /** Window for accepting an upstream verified-hop marker. Default 60_000ms. */\n verifiedHopMaxAgeMs?: number;\n /**\n * Automatically record grant/deny decisions for every MCP call. Default\n * `true` — matches the express adapter.\n */\n recordDecisions?: boolean;\n /** Forward runtime challenge (default `true`). */\n enableRuntimeChallenge?: boolean;\n}\n\n/**\n * Default MCP denied handler.\n *\n * Round-10 (#47, O5): mirrors the express adapter — surfaces `failures[]`\n * and `correlationId` on the response so partners can render rich UX and\n * tie a denial to a log line. Also stamps `X-Astra-Gateway-Mode: enforced`\n * (#49/O10) so the header reliably distinguishes gate-evaluated denials\n * from gate-skipped pass-throughs.\n */\n/**\n * Round-13: shared single-value HTTP header reader. Same shape used for\n * both `X-Astra-Purpose` and `X-Astra-Action` extraction (symmetric\n * fallback chain — see `mcpToPdlss` for the full precedence rule).\n * Returns the first value if the header repeats (Express turns repeated\n * headers into an array); returns undefined when the header is absent.\n */\nfunction readSingleHeader(value: string | string[] | undefined): string | undefined {\n if (typeof value === 'string') return value;\n if (Array.isArray(value)) return value[0];\n return undefined;\n}\n\nfunction defaultMcpDenied(result: VerificationResult, req: Request, res: Response): void {\n // JSON-RPC error envelope so MCP-aware clients render it correctly.\n const id = (req.body as Record<string, unknown> | undefined)?.id ?? null;\n // Round-18 G4: see express.defaultOnDenied for full rationale on the\n // identity-vs-policy split → 401/403 mapping. Same logic here so MCP\n // clients get HTTP status semantics aligned with REST adapters.\n const status = !result.identityVerified ? 401 : 403;\n\n res.setHeader('X-Astra-Gateway-Mode', 'enforced');\n\n res.status(status).json({\n jsonrpc: '2.0',\n id,\n error: {\n // JSON-RPC error codes:\n // -32000 → unauthorized (no identity resolved)\n // -32001 → insufficient access (identity OK, policy denied)\n code: !result.identityVerified ? -32000 : -32001,\n message: result.denialReasons?.[0] ?? 'Access denied',\n data: {\n accessLevel: result.accessLevel,\n guidance: result.guidance,\n // Round-10: aggregated per-dimension detail + correlation handle.\n failures: result.failures,\n correlationId: result.correlationId,\n },\n },\n });\n}\n\n/**\n * Resolve the effective minimum access level for a parsed MCP request.\n * Order: per-tool override → per-method override → tier-default from\n * `mcpRiskTier`.\n *\n * v2.3.9 (defect #34) returns the SOURCE of the resolution alongside the\n * level so the gate-failure site can attribute a local override correctly\n * (`toolGate` / `methodGate` / `tier`) when reporting back to the\n * activity feed.\n */\nfunction resolveMinAccessLevel(\n parsed: ParsedMcpRequest,\n opts: { toolGates?: Record<string, AccessLevel>; methodGates?: Record<string, AccessLevel> }\n): { level: AccessLevel; source: 'toolGate' | 'methodGate' | 'tier' } {\n if (parsed.toolName && opts.toolGates && opts.toolGates[parsed.toolName] !== undefined) {\n return { level: opts.toolGates[parsed.toolName], source: 'toolGate' };\n }\n if (opts.methodGates && opts.methodGates[parsed.method] !== undefined) {\n return { level: opts.methodGates[parsed.method], source: 'methodGate' };\n }\n return { level: mcpRiskTier(parsed), source: 'tier' };\n}\n\n/**\n * Create the MCP middleware. Attach AFTER `express.json()` — the body must\n * already be a parsed object.\n */\nexport function createMcpMiddleware(options: McpMiddlewareOptions): RequestHandler {\n const {\n toolGates,\n methodGates,\n onAgentIdMismatch = 'reject',\n skip = false,\n onDenied = defaultMcpDenied,\n trustVerifiedHop = true,\n verifiedHopMaxAgeMs,\n recordDecisions,\n enableRuntimeChallenge = true,\n ...config\n } = options;\n\n return async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n if (skip) return next();\n\n const parsed = parseMcpJsonRpc(req.body);\n if (!parsed) {\n // Not a JSON-RPC body. Either the route is misconfigured or the\n // client sent a non-MCP payload. We don't 400 here — let the actual\n // MCP server handler render its own error so the middleware doesn't\n // pre-empt valid framework error shapes.\n if (config.setPassThroughHeader) {\n // Round-10 (#49, O10): `unenforced` describes the GATE state, not\n // the downstream response. Renamed from the ambiguous\n // `pass-through` (which partners read as \"request succeeded\").\n res.setHeader('X-Astra-Gateway-Mode', 'unenforced');\n res.setHeader('X-Astra-Gateway-Reason', 'non-jsonrpc-body');\n }\n return next();\n }\n req.mcpRequest = parsed;\n\n // ── Identity reconciliation (defect d) ─────────────────────────────\n // Header value is the SDK-canonical slot; body slot exists for legacy\n // hand-written tool callers and the MCP `_meta.astrasync.agentId`\n // convention.\n const headerRaw = req.headers['x-astra-id'] ?? req.headers['x-astra-agentid'];\n const headerAstraId =\n typeof headerRaw === 'string'\n ? headerRaw\n : Array.isArray(headerRaw)\n ? headerRaw[0]\n : undefined;\n const bodyAstraId = parsed.agentIdFromBody;\n\n let effectiveAstraId: string | undefined;\n if (headerAstraId && bodyAstraId && headerAstraId !== bodyAstraId) {\n if (onAgentIdMismatch === 'reject') {\n const id = (req.body as Record<string, unknown>)?.id ?? null;\n res.status(400).json({\n jsonrpc: '2.0',\n id,\n error: {\n code: -32602,\n message: 'AGENT_ID_MISMATCH',\n data: {\n detail:\n 'The agent id in the X-Astra-Id header disagrees with params._meta.astrasync.agentId / params.arguments.agent_id. Reconcile before calling the tool — see https://astrasync.ai/docs/mcp-integration#identity-reconciliation.',\n headerAstraId,\n bodyAstraId,\n },\n },\n });\n return;\n }\n effectiveAstraId = onAgentIdMismatch === 'prefer-header' ? headerAstraId : bodyAstraId;\n } else {\n effectiveAstraId = headerAstraId ?? bodyAstraId;\n }\n\n // ── Inner-hop dedupe (defect c) ────────────────────────────────────\n // If a trusted upstream MCP hop already verified this exact ASTRA-id\n // a few ms ago, we accept the marker and skip a redundant verify-access\n // call. Only valid when the header is fresh AND matches the agent id\n // we resolved above.\n if (trustVerifiedHop && effectiveAstraId) {\n const hopRaw = req.headers[MCP_VERIFIED_HOP_HEADER.toLowerCase()];\n const hopValue =\n typeof hopRaw === 'string' ? hopRaw : Array.isArray(hopRaw) ? hopRaw[0] : undefined;\n const marker = parseVerifiedHop(hopValue);\n if (\n isVerifiedHopValidFor(marker, effectiveAstraId, {\n ...(verifiedHopMaxAgeMs !== undefined ? { maxAgeMs: verifiedHopMaxAgeMs } : {}),\n })\n ) {\n // Skip verify-access — pass straight through. Don't re-emit the\n // header since the MCP framework will issue the response (the\n // outer hop already tagged it for any further inner hops).\n return next();\n }\n }\n\n // ── Resolve gating ─────────────────────────────────────────────────\n const { level: minAccessLevel, source: gateSource } = resolveMinAccessLevel(parsed, {\n toolGates,\n methodGates,\n });\n\n // ── Build verify-access request ────────────────────────────────────\n // Round-13 (R13-5) — credentials extraction hoisted above the\n // mcp-tier-none short-circuit (mirrors round-12 F9 express adapter\n // restructure). The `evaluateAlwaysIfCredentialed` flag lets the\n // caller turn unenforced tier-none calls into evaluated-not-enforced\n // calls when credentials are present, so the agent verification\n // result populates `req.agentVerification` for tier-aware handler\n // rendering (e.g. anonymous vs verified MCP tool listings).\n const credentials = extractCredentials(\n req.headers as Record<string, string | string[] | undefined>,\n req.query as Record<string, string | undefined>\n );\n // Override the SDK's default credential extraction with the resolved\n // ASTRA-id so the verify-access call sees the post-precedence value\n // (defect d). When neither header nor body supplied an id, the SDK's\n // anonymous-canonical-flow handles it.\n if (effectiveAstraId) credentials.astraId = effectiveAstraId;\n\n // Risk tier `none` short-circuit. Default behaviour: skip\n // verify-access (handshake / introspection must work for\n // unregistered probes). With `evaluateAlwaysIfCredentialed: true`\n // AND credentials present, fall through to verify-access for the\n // audit trail; the post-verify gate-skipping branch below handles\n // the rendering side. Round-12 F9 parity (closes the round-12\n // deferral).\n const shouldEnforce = minAccessLevel !== 'none';\n if (\n minAccessLevel === 'none' &&\n (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)\n ) {\n if (config.setPassThroughHeader) {\n // Round-10 (#49, O10): `unenforced` describes the GATE state, not\n // the downstream response.\n res.setHeader('X-Astra-Gateway-Mode', 'unenforced');\n res.setHeader('X-Astra-Gateway-Reason', 'mcp-tier-none');\n }\n return next();\n }\n\n // Round-12 (F19) + round-13 (R13-1, R13-2): symmetric purpose+action\n // resolution. Per `feedback_symmetric_fallbacks_for_symmetric_concepts.md`,\n // both concepts share the precedence chain documented at\n // `mcpToPdlss`:\n // header → _meta.astrasync.<concept> → params.arguments.<concept> → default\n //\n // Round-12 shipped purpose with `header → _meta → default`;\n // round-13 R13-1 closed the `params.arguments.purpose` fallback\n // gap. Round-13 R13-2 ships action with the same full chain in\n // one round (not staggered) to pre-empt the parallel \"I set\n // action in arguments and it didn't take\" support tickets.\n const headerPurpose = readSingleHeader(req.headers['x-astra-purpose']);\n const headerAction = readSingleHeader(req.headers['x-astra-action']);\n const pdlss = mcpToPdlss(parsed, headerPurpose, headerAction);\n\n // Telemetry: debug log per resolution. Adoption tracking, support\n // triage, and the `default_*` / `transport_layer` decay signals\n // all read this. Both purpose and action emit their source so we\n // can spot which integration path each partner is using.\n if (config.debug) {\n // eslint-disable-next-line no-console\n console.debug('[mcp-middleware] pdlss resolved', {\n purpose_source: pdlss.purposeSource,\n resolved_purpose: pdlss.purpose,\n action_source: pdlss.actionSource,\n resolved_action: pdlss.action,\n });\n }\n\n const counterpartyUrl =\n config.counterpartyUrl || `${req.protocol}://${req.get('host')}${req.path}`;\n const shouldRecordDecisions = recordDecisions !== false;\n\n const result = await verify(config, {\n credentials,\n purpose: pdlss.purpose,\n action: pdlss.action,\n resource: pdlss.resource,\n // Round-12 (F19): mark transport protocol separately from intent.\n // The MCP middleware always sets this to 'mcp'; non-MCP callers\n // leave it unset (server-side default is 'rest').\n invocationProtocol: 'mcp',\n createSession: shouldRecordDecisions,\n counterpartyUrl,\n counterpartyType: config.counterpartyType || 'mcp_server',\n enableRuntimeChallenge,\n callerMetadata: {\n sourceIp: req.ip,\n userAgent: req.headers['user-agent'] as string | undefined,\n host: req.headers.host as string | undefined,\n },\n });\n\n req.agentVerification = result;\n const sessionId = (result as EnhancedVerificationResult).sessionId;\n const correlationId = (result as EnhancedVerificationResult).correlationId;\n\n // v2.3.9 (defect #30): denied verifications short-circuit BEFORE the\n // gate-level comparison. See express.ts for the full rationale —\n // mirroring it here so the MCP path inherits the same belt-and-braces\n // protection against access-level/help-payload conflation.\n // Round-18 G4: short-circuit on either axis failing.\n if (!result.identityVerified || !result.policyAllowed) {\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'denied', result.denialReasons?.[0]).catch(() => {});\n }\n onDenied(result, req, res);\n return;\n }\n\n // Round-13 (R13-5): evaluation-without-enforcement parity with the\n // express F9 adapter. When the route is `none` but we ran\n // verify-access because `evaluateAlwaysIfCredentialed: true` AND\n // credentials were present, skip the gates and call next() — the\n // result is on `req.agentVerification` for the MCP handler to\n // render tier-aware responses (e.g. anonymous vs verified\n // tool-listing on the same `/mcp` endpoint).\n if (!shouldEnforce) {\n if (config.setPassThroughHeader) {\n res.setHeader('X-Astra-Gateway-Mode', 'enforced');\n res.setHeader('X-Astra-Gateway-Reason', 'evaluated-not-enforced');\n }\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'granted').catch(() => {});\n }\n return next();\n }\n\n if (!hasMinimumAccess(result.accessLevel, minAccessLevel)) {\n // Round-12 (F12): synthesise the structured failure entry so the\n // partner-facing response carries the same shape as every other\n // denial dimension. Guidance positions step-up only — increasing\n // trust score or lowering the route floor both read as gaming the\n // gate. Step-up flow ships separately this month.\n const insufficientFailure = {\n dimension: 'access_level.insufficient',\n message: `Tool requires accessLevel '${minAccessLevel}'; agent has '${result.accessLevel}'.`,\n guidance:\n \"Request elevated access via step-up verification (coming soon — ships this month). Step-up lets the agent owner approve a one-time elevation for this specific counterparty + purpose without changing the agent's baseline trust score.\",\n };\n result.failures = [...(result.failures ?? []), insufficientFailure];\n result.denialReasons = [...(result.denialReasons ?? []), insufficientFailure.message];\n\n // v2.3.9 (defect #34): server granted but local enforcement\n // (toolGate / methodGate / tier floor) is rejecting. Record this\n // as a local override so the activity feed surfaces the\n // dashboard-vs-runtime divergence as a distinct event.\n //\n // v2.3.10 (defect #34, round-4): anonymous traffic has no session\n // → fall back to `correlationId` and the sessionless local-override\n // endpoint. Authenticated traffic still uses sessionId/recordDecision.\n if (shouldRecordDecisions) {\n const overrideKind: 'toolGate' | 'methodGate' | 'other' =\n gateSource === 'toolGate'\n ? 'toolGate'\n : gateSource === 'methodGate'\n ? 'methodGate'\n : 'other';\n const override = {\n overriddenBy: overrideKind,\n ...(parsed.toolName && { toolName: parsed.toolName }),\n requestedLevel: minAccessLevel,\n grantedLevel: result.accessLevel,\n };\n if (sessionId) {\n recordDecision(config, sessionId, 'denied', result.denialReasons?.[0], override).catch(\n () => {}\n );\n } else if (correlationId) {\n recordAnonymousLocalOverride(\n config,\n correlationId,\n override,\n result.denialReasons?.[0]\n ).catch(() => {});\n }\n }\n onDenied(result, req, res);\n return;\n }\n\n // ── Tag the outbound response with X-Astra-Verified-Hop ────────────\n // Inner-hop REST endpoints called by this tool can read the header\n // and skip a duplicate verify-access. We set it on the response so\n // downstream proxies see it; tools that perform fetch() to an inner\n // hop should also forward it themselves (the MCP server framework\n // controls outbound calls — out of scope here).\n if (effectiveAstraId) {\n res.setHeader(\n MCP_VERIFIED_HOP_HEADER,\n serializeVerifiedHop({\n astraId: effectiveAstraId,\n ...(sessionId ? { sessionId } : {}),\n checkedAt: Date.now(),\n })\n );\n }\n\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'granted').catch(() => {});\n }\n // v2.3.8 (defect #26): relay X-Astra-Unverified-Warning when the\n // server returned an audit-mode advisory.\n const enhancedResult = result as EnhancedVerificationResult;\n if (enhancedResult.warningHeader) {\n res.setHeader(enhancedResult.warningHeader.name, enhancedResult.warningHeader.value);\n }\n next();\n } catch (error) {\n // Fail open by default — the underlying MCP server handler still\n // exists and can apply its own access control. A logger hook is a\n // future enhancement.\n // eslint-disable-next-line no-console\n console.error('[VerificationGateway/MCP] Middleware error:', error);\n next();\n }\n };\n}\n\n// Re-export the helpers so consumers can mix-and-match (e.g. read the\n// verified-hop header themselves on a custom inner-hop handler).\nexport {\n parseMcpJsonRpc,\n mcpToPdlss,\n mcpRiskTier,\n serializeVerifiedHop,\n parseVerifiedHop,\n isVerifiedHopValidFor,\n MCP_VERIFIED_HOP_HEADER,\n};\nexport type { ParsedMcpRequest } from '../transport/mcp-server';\n","import type { ApiErrorResponse } from './types';\n\n/** Base error class for AstraSync SDK errors. */\nexport class AstraSyncError extends Error {\n public readonly code?: string;\n public readonly statusCode: number;\n\n constructor(message: string, statusCode: number, code?: string) {\n super(message);\n this.name = 'AstraSyncError';\n this.statusCode = statusCode;\n this.code = code;\n }\n}\n\n/** Thrown when KYD verification is required before agent registration. */\nexport class KYDRequiredError extends AstraSyncError {\n public readonly kydUrl: string;\n public readonly ownerNotified: boolean;\n\n constructor(response: ApiErrorResponse) {\n const kydUrl = response.kydUrl || 'https://astrasync.ai/developer-profile';\n super(\n `KYD verification required before registering agents.\\nComplete your KYD profile at: ${kydUrl}`,\n 403,\n 'KYD_REQUIRED'\n );\n this.name = 'KYDRequiredError';\n this.kydUrl = kydUrl;\n this.ownerNotified = response.ownerNotified || false;\n }\n}\n\n/** Thrown when authentication fails. */\nexport class AuthenticationError extends AstraSyncError {\n constructor(message: string) {\n super(message, 401, 'AUTH_FAILED');\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Thrown by `register({ waitForApproval: true })` when the owner denies the\n * pending registration request. The `reason` field, when present, mirrors the\n * deny note the owner left in the dashboard.\n */\nexport class RegistrationDeniedError extends AstraSyncError {\n public readonly requestId: string;\n public readonly reason?: string;\n\n constructor(requestId: string, reason?: string) {\n super(\n `Registration request ${requestId} was denied by the account owner.${reason ? ` Reason: ${reason}` : ''}`,\n 403,\n 'REGISTRATION_DENIED'\n );\n this.name = 'RegistrationDeniedError';\n this.requestId = requestId;\n this.reason = reason;\n }\n}\n\n/**\n * Thrown by `register({ waitForApproval: true })` when the pending request\n * passes its 14-day TTL with no owner decision. The agent must re-submit.\n */\nexport class RegistrationExpiredError extends AstraSyncError {\n public readonly requestId: string;\n\n constructor(requestId: string) {\n super(\n `Registration request ${requestId} expired before the owner approved it. Submit a new registration request.`,\n 410,\n 'REGISTRATION_EXPIRED'\n );\n this.name = 'RegistrationExpiredError';\n this.requestId = requestId;\n }\n}\n\n/**\n * Thrown by `register({ waitForApproval: true })` when the caller's local\n * `timeoutMs` elapses before the owner makes a decision. The request is still\n * live server-side — poll `pollRegistration(requestId)` to resume waiting, or\n * call `waitForApproval` again with a longer timeout.\n */\nexport class RegistrationTimeoutError extends AstraSyncError {\n public readonly requestId: string;\n\n constructor(requestId: string) {\n super(\n `Timed out waiting for owner approval of registration request ${requestId}. The request is still active server-side; poll the request to resume waiting.`,\n 408,\n 'REGISTRATION_TIMEOUT'\n );\n this.name = 'RegistrationTimeoutError';\n this.requestId = requestId;\n }\n}\n","import type {\n AstraSyncConfig,\n RegisterOptions,\n RegisterResult,\n WaitForApprovalOptions,\n PendingRegistrationResponse,\n PollRegistrationResult,\n RegistrationResponse,\n VerifyResponse,\n HealthResponse,\n ApiErrorResponse,\n AgentRecord,\n} from './types';\nimport {\n AstraSyncError,\n KYDRequiredError,\n AuthenticationError,\n RegistrationDeniedError,\n RegistrationExpiredError,\n RegistrationTimeoutError,\n} from './errors';\n\nconst DEFAULT_BASE_URL = 'https://astrasync.ai';\n\nconst sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\n/**\n * AstraSync SDK client for registering and managing AI agents.\n *\n * @example\n * ```typescript\n * const client = new AstraSync({ apiKey: 'kya_your_api_key' });\n * const result = await client.register({\n * name: 'My Agent',\n * model: { modelName: 'gpt-4o', modelProvider: 'openai', modelType: 'llm' },\n * });\n * ```\n *\n * For staging, pass `baseUrl: 'https://staging.astrasync.ai'`.\n */\nexport class AstraSync {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly email?: string;\n private readonly password?: string;\n private readonly privateKey?: string;\n private cachedJwt?: string;\n private jwtExpiresAt?: number;\n\n constructor(config: AstraSyncConfig = {}) {\n let raw = (config.baseUrl || process.env.ASTRASYNC_API_URL || DEFAULT_BASE_URL).replace(\n /\\/+$/,\n ''\n );\n // Round-10 (O2): tolerate the verify-side convention. `GatewayConfig.apiBaseUrl`\n // is documented as `https://astrasync.ai/api` (with /api), but\n // `AstraSyncConfig.baseUrl` is documented as the bare origin. Partners\n // passing the verify-style URL to the registration client hit a 404\n // because we'd then append `/api/agents/register` → double /api. Strip\n // a trailing `/api` and warn once so the partner can fix the source.\n if (raw.toLowerCase().endsWith('/api')) {\n raw = raw.slice(0, -'/api'.length);\n if (config.baseUrl && !config.silent) {\n // eslint-disable-next-line no-console\n console.warn(\n `[AstraSync] baseUrl '${config.baseUrl}' had a trailing /api — stripped to '${raw}'. ` +\n `Pass the bare origin (e.g. 'https://astrasync.ai' or 'https://staging.astrasync.ai') ` +\n `to AstraSync(). The /api suffix is the verify-gateway (GatewayConfig.apiBaseUrl) convention.`\n );\n }\n }\n this.baseUrl = raw;\n\n // Env fallback is opt-OUT: server-side wrappers (MCP tool handlers,\n // gateway adapters) pass `disableEnvFallback: true` so a no-credentials\n // call from a user-facing flow cannot silently authenticate as the host\n // process's platform-attribution key. CLIs / scripts that legitimately\n // rely on ASTRASYNC_API_KEY keep working under the default.\n this.apiKey = config.disableEnvFallback\n ? config.apiKey\n : config.apiKey || process.env.ASTRASYNC_API_KEY;\n this.email = config.email;\n this.password = config.password;\n this.privateKey = config.privateKey;\n\n // Defense-in-depth: warn when env fallback actually fires under the\n // default (non-strict) config. Surfaces the \"I'm running as platform\"\n // foot-gun before it becomes a security bug. Gated by !silent.\n if (\n !config.apiKey &&\n !config.disableEnvFallback &&\n process.env.ASTRASYNC_API_KEY &&\n !config.silent\n ) {\n // eslint-disable-next-line no-console\n console.warn(\n '[AstraSync] No apiKey passed to constructor; using process.env.ASTRASYNC_API_KEY. ' +\n 'If this code wraps user-facing flows (e.g. MCP tool handlers), pass ' +\n 'disableEnvFallback: true to prevent ambient credentials from impersonating callers. ' +\n 'See https://astrasync.ai/docs/agent-access#disableenvfallback for details.'\n );\n }\n\n if (!this.apiKey && !this.email) {\n throw new AuthenticationError(\n 'Authentication required. Provide apiKey, or email+password. ' +\n 'Set ASTRASYNC_API_KEY env var or pass config to constructor.'\n );\n }\n\n if (this.email && !this.password) {\n throw new AuthenticationError('Password is required when using email authentication.');\n }\n }\n\n /**\n * Register a new AI agent on the AstraSync KYA Platform.\n *\n * The backend response depends on auth context:\n * - **Crypto-keypair signed** (`privateKey` configured): synchronous 201,\n * returns `{ status: 'active', agent }`.\n * - **API-key only** (no signature): 202 pending, returns\n * `{ status: 'pending_approval', requestId, pollUrl, expiresAt }`. The\n * owner is notified by email and a dashboard alert is emitted; the agent\n * becomes active only after the owner approves.\n *\n * Blocking mode: pass `{ waitForApproval: true }` to have the SDK poll the\n * request until it resolves, then return the live agent record. The promise\n * rejects with `RegistrationDeniedError`, `RegistrationExpiredError`, or\n * `RegistrationTimeoutError` on the corresponding terminal states.\n *\n * @example Non-blocking (default — best for serverless / scheduled agents):\n * ```typescript\n * const result = await sdk.register({ name, pdlss });\n * if (result.status === 'pending_approval') {\n * storeRequestId(result.requestId);\n * return; // function exits; resume later via pollRegistration()\n * }\n * ```\n *\n * @example Blocking (best for long-running services + CLI):\n * ```typescript\n * const agent = await sdk.register({\n * name, pdlss, waitForApproval: true, timeoutMs: 600_000,\n * onPending: ({ ageMs }) => console.log(`waiting ${ageMs}ms`),\n * });\n * ```\n */\n async register(\n options: RegisterOptions & WaitForApprovalOptions\n ): Promise<RegisterResult | AgentRecord> {\n const body: Record<string, unknown> = {\n name: options.name,\n ...(options.description && { description: options.description }),\n ...(options.agentType && { agentType: options.agentType }),\n ...(options.apiEndpoint && { apiEndpoint: options.apiEndpoint }),\n ...(options.model && { model: options.model }),\n ...(options.framework && { framework: options.framework }),\n ...(options.protocols && { protocols: options.protocols }),\n ...(options.metadata && { metadata: options.metadata }),\n ...(options.pdlss && { pdlss: options.pdlss }),\n };\n\n const { status, body: raw } = await this.requestWithStatus<\n RegistrationResponse | PendingRegistrationResponse\n >('POST', '/api/agents/register', body);\n\n if (status === 201) {\n const activeBody = raw as RegistrationResponse;\n const active: RegisterResult = {\n status: 'active',\n agent: activeBody.data.agent,\n // Round-12 (F16): pass backend advisories through verbatim.\n // Pre-fix the SDK whitelisted five fields and silently dropped\n // `warnings`, which left partners with no signal that\n // `no_callback_endpoint` (or future advisories) had fired.\n ...(activeBody.warnings && { warnings: activeBody.warnings }),\n };\n return active;\n }\n\n // 202 Accepted — owner approval required.\n const pendingBody = raw as PendingRegistrationResponse;\n const pending: RegisterResult = {\n status: 'pending_approval',\n requestId: pendingBody.requestId,\n expiresAt: pendingBody.expiresAt,\n pollUrl: pendingBody.pollUrl,\n message: pendingBody.message,\n // Round-12 (F16): same pass-through on the pending path.\n ...(pendingBody.warnings && { warnings: pendingBody.warnings }),\n };\n\n if (!options.waitForApproval) return pending;\n\n return this.waitForApproval(pendingBody.requestId, options);\n }\n\n /**\n * Poll the current state of a pending-approval registration request.\n *\n * Useful for caller-driven polling when `waitForApproval: false` (the\n * default). The endpoint is unauthenticated — pass the `requestId` that\n * was returned from the 202 response.\n *\n * @returns `state: 'pending'` while awaiting; `'approved'` carries the\n * minted agent in `agent`; `'denied'` may carry the owner's\n * `reason`; `'expired'` is terminal after 14 days.\n */\n async pollRegistration(requestId: string): Promise<PollRegistrationResult> {\n const url = `${this.baseUrl}/api/agents/request-registration/${requestId}`;\n const res = await fetch(url, { headers: { Accept: 'application/json' } });\n if (!res.ok) {\n const errBody = (await res.json().catch(() => ({}))) as ApiErrorResponse;\n throw new AstraSyncError(\n errBody.error || `pollRegistration failed: ${res.status}`,\n res.status,\n errBody.code\n );\n }\n return (await res.json()) as PollRegistrationResult;\n }\n\n /**\n * Block until a pending registration request resolves to a terminal state.\n * Resolves to the live `AgentRecord` on approval; rejects with the matching\n * Registration*Error on deny/expire/timeout. Usually called via\n * `register({ waitForApproval: true })`, but exposed for callers that want\n * to fire-and-forget the initial register call and resume waiting later\n * (e.g. after restoring a stored `requestId` on cold start).\n */\n async waitForApproval(\n requestId: string,\n options: WaitForApprovalOptions = {}\n ): Promise<AgentRecord> {\n const timeoutMs = options.timeoutMs ?? 10 * 60 * 1000;\n const pollIntervalMs = options.pollIntervalMs ?? 5_000;\n const start = Date.now();\n const deadline = start + timeoutMs;\n\n while (Date.now() < deadline) {\n const result = await this.pollRegistration(requestId);\n const ageMs = Date.now() - start;\n options.onPending?.({ requestId, ageMs });\n\n if (result.state === 'approved') {\n if (!result.agent) {\n throw new AstraSyncError(\n `Registration ${requestId} reported approved but no agent payload returned.`,\n 500\n );\n }\n return result.agent;\n }\n if (result.state === 'denied') {\n throw new RegistrationDeniedError(requestId, result.reason);\n }\n if (result.state === 'expired') {\n throw new RegistrationExpiredError(requestId);\n }\n await sleep(pollIntervalMs);\n }\n throw new RegistrationTimeoutError(requestId);\n }\n\n /**\n * Look up an agent's public profile by ASTRA ID or UUID.\n */\n async verify(agentId: string): Promise<VerifyResponse> {\n return this.request<VerifyResponse>('GET', `/api/agents/verify/${agentId}`);\n }\n\n /**\n * Check API health.\n */\n async health(): Promise<HealthResponse> {\n const res = await fetch(`${this.baseUrl}/api/health/`);\n if (!res.ok) {\n throw new AstraSyncError(`Health check failed: ${res.status}`, res.status);\n }\n return res.json() as Promise<HealthResponse>;\n }\n\n // ── Private helpers ──────────────────────────────────────────────\n\n private async request<T>(method: string, endpoint: string, body?: unknown): Promise<T> {\n const { body: parsed } = await this.requestWithStatus<T>(method, endpoint, body);\n return parsed;\n }\n\n /**\n * Variant of {@link request} that also returns the HTTP status code, so\n * callers can branch on 201 vs 202 (or other success codes) without losing\n * type information about the response body.\n */\n private async requestWithStatus<T>(\n method: string,\n endpoint: string,\n body?: unknown\n ): Promise<{ status: number; body: T }> {\n const url = `${this.baseUrl}${endpoint}`;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Set auth header\n const token = await this.getAuthToken();\n headers['Authorization'] = `Bearer ${token}`;\n\n // Sign request if private key is configured\n if (this.privateKey) {\n const signature = await this.signRequest(method, endpoint, body || {});\n headers['X-AstraSync-Signature'] = signature;\n }\n\n const res = await fetch(url, {\n method,\n headers,\n ...(body ? { body: JSON.stringify(body) } : {}),\n });\n\n if (!res.ok) {\n const errorBody = (await res\n .json()\n .catch(() => ({ error: res.statusText }))) as ApiErrorResponse;\n\n // Handle KYD_REQUIRED specifically\n if (res.status === 403 && errorBody.code === 'KYD_REQUIRED') {\n throw new KYDRequiredError(errorBody);\n }\n\n throw new AstraSyncError(\n errorBody.error || `Request failed: ${res.status}`,\n res.status,\n errorBody.code\n );\n }\n\n return { status: res.status, body: (await res.json()) as T };\n }\n\n private async getAuthToken(): Promise<string> {\n // API key auth — use directly\n if (this.apiKey) {\n return this.apiKey;\n }\n\n // Email+password — login and cache JWT\n if (this.cachedJwt && this.jwtExpiresAt && Date.now() < this.jwtExpiresAt) {\n return this.cachedJwt;\n }\n\n const res = await fetch(`${this.baseUrl}/api/auth/login`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email: this.email, password: this.password }),\n });\n\n if (!res.ok) {\n const errorBody = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n throw new AuthenticationError(\n (errorBody.message as string) || (errorBody.error as string) || 'Login failed'\n );\n }\n\n const data = (await res.json()) as { data: { token: string } };\n this.cachedJwt = data.data.token;\n // Cache for 6 days (tokens expire in 7)\n this.jwtExpiresAt = Date.now() + 6 * 24 * 60 * 60 * 1000;\n\n return this.cachedJwt;\n }\n\n /**\n * Sign a request using secp256k1 (ethers.js).\n * Canonical message format: METHOD:ENDPOINT:SORTED_JSON_BODY\n * Must match apps/backend/src/services/signature-verify.service.ts exactly.\n */\n private async signRequest(method: string, endpoint: string, body: unknown): Promise<string> {\n const { Wallet } = await import('ethers');\n const sorted = this.sortObjectKeys(body);\n const canonical = `${method}:${endpoint}:${JSON.stringify(sorted)}`;\n const wallet = new Wallet(this.privateKey!);\n return wallet.signMessage(canonical);\n }\n\n /** Recursively sort object keys for canonical JSON representation. */\n private sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n if (Array.isArray(obj)) {\n return obj.map((item) => this.sortObjectKeys(item));\n }\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = this.sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n return sorted;\n }\n}\n","/**\n * Guidance envelope for credentials-required cases.\n *\n * Round-18 B3b: lifted from `apps/mcp-server/src/tools/agent-registration.ts`\n * (which had inlined the shape) so partners writing their own wrappers\n * (custom MCP servers, Express middleware around registration, gateway\n * adapters) consume a single source of truth instead of re-implementing the\n * five-step boilerplate.\n *\n * The envelope is what an agent (or wrapping MCP client) sees when it calls\n * `register_agent` with no AstraSync credentials. It tells the calling agent\n * (a) what failed (`status: 'credentials_required'`), (b) where to register\n * (`registrationUrl`), (c) where the relevant docs are (`documentationUrl`),\n * and (d) the ordered next-actions (`steps`).\n */\n\nexport interface GuidanceEnvelope {\n /**\n * Single-literal today. Expand to a union (e.g.\n * `'credentials_required' | 'kyd_required' | …`) when a second guidance\n * status emerges. Don't pre-emptively widen — the literal pins the shape.\n */\n status: 'credentials_required';\n message: string;\n guidance: {\n message: string;\n registrationUrl: string;\n documentationUrl: string;\n steps: string[];\n };\n}\n\nexport interface BuildGuidanceParams {\n /**\n * Bare origin of the AstraSync deployment the caller should register at,\n * e.g. `https://astrasync.ai` or `https://staging.astrasync.ai`. No\n * trailing slash, no `/api` suffix — registrationUrl and documentationUrl\n * are templated relative to this origin.\n */\n origin: string;\n /**\n * Overrides the top-level `message` (the short summary the agent sees).\n * Defaults to the error message from the SDK's `AuthenticationError`\n * when present, else a generic \"credentials required\" line.\n */\n message?: string;\n /**\n * Overrides the documentation path. Defaults to `/docs/agent-access`.\n */\n documentationPath?: string;\n}\n\n/**\n * Build the credentials-required guidance envelope.\n *\n * This is the canonical builder — MCP wrappers (`agent-registration.ts`),\n * Express middleware in custom integrations, and any other partner-side\n * wrapper that needs to surface \"you need to register\" should call this\n * rather than reconstructing the shape inline. Inline reconstruction\n * pre-round-18 led to drift between wrappers; this consolidates it.\n *\n * @example\n * ```ts\n * import { buildGuidance } from '@astrasyncai/verification-gateway';\n *\n * try {\n * const sdk = new AstraSync({ apiKey: callerApiKey, disableEnvFallback: true });\n * // ...\n * } catch (err) {\n * if (err instanceof AuthenticationError) {\n * return buildGuidance({ origin: 'https://astrasync.ai', message: err.message });\n * }\n * throw err;\n * }\n * ```\n */\nexport function buildGuidance(params: BuildGuidanceParams): GuidanceEnvelope {\n const origin = params.origin.replace(/\\/+$/, '');\n const docsPath = params.documentationPath ?? '/docs/agent-access';\n const message = params.message ?? 'AstraSync registration requires credentials.';\n\n return {\n status: 'credentials_required',\n message,\n guidance: {\n message:\n 'AstraSync registration requires credentials. Get an account + API key, then call register_agent again.',\n registrationUrl: `${origin}/register`,\n documentationUrl: `${origin}${docsPath.startsWith('/') ? docsPath : `/${docsPath}`}`,\n steps: [\n 'Visit registrationUrl and create an AstraSync account (or log in if you have one).',\n 'Generate an API key from Settings → API Keys.',\n 'Re-call register_agent with the apiKey populated.',\n 'After registration returns status: pending_approval, the owner approves via email.',\n 'Use poll_registration({ requestId }) to retrieve the astraId once approved.',\n ],\n },\n };\n}\n","/**\n * Agent-Side SDK Module\n *\n * Tools for AI agents to present credentials, handle challenges,\n * and interact with the AstraSync verification protocol.\n */\n\nexport { AgentClient } from './client';\nexport { ChallengeHandler } from './challenge-handler';\nexport { formatPDLSSForTransport, parsePDLSSFromTransport } from './pdlss-formatter';\nexport type { PDLSSConfig, TransportPDLSS } from './pdlss-formatter';\nexport { recordDecision } from './decision-client';\nexport { AstraSyncSdkError, OwnershipMismatchError } from './errors';\n","/**\n * Agent-side SDK errors.\n */\n\nexport class AstraSyncSdkError extends Error {\n readonly code: string;\n constructor(code: string, message: string) {\n super(message);\n this.name = 'AstraSyncSdkError';\n this.code = code;\n }\n}\n\n/**\n * Thrown when the API key used to initialise AgentClient is not owned by\n * the same account that registered the configured ASTRA-id. Blocks the\n * client from doing anything under a mismatched identity.\n */\nexport class OwnershipMismatchError extends AstraSyncSdkError {\n readonly astraId: string;\n\n constructor(astraId: string) {\n super(\n 'ownership_mismatch',\n `The configured API key does not own agent ${astraId}. Refusing to initialise.`\n );\n this.name = 'OwnershipMismatchError';\n this.astraId = astraId;\n }\n}\n","/**\n * AgentClient — Credential Presentation\n *\n * Agent-side SDK for automatically injecting AstraSync credentials\n * into outgoing requests across all supported protocols.\n */\n\nimport type { AstraSyncCredentials, ProtocolTransport } from '../types';\nimport { setHttpHeaders } from '../transport/http';\nimport { setA2AMetadata } from '../transport/a2a';\nimport { setMcpMeta } from '../transport/mcp';\nimport { applyCredentials } from '../transport';\nimport { OwnershipMismatchError } from './errors';\n\ninterface AgentClientConfig {\n agentId: string;\n verifyUrl?: string;\n challengeUrl?: string;\n pdlss?: AstraSyncCredentials['pdlss'];\n /** Base URL for AstraSync API (used for ownership check). Defaults to https://astrasync.ai/api */\n apiBaseUrl?: string;\n /** API key used to authenticate ownership check + other authenticated calls. */\n apiKey?: string;\n}\n\ninterface FetchOptions extends RequestInit {\n purpose?: string;\n action?: string;\n}\n\nexport class AgentClient {\n private credentials: AstraSyncCredentials;\n private apiBaseUrl: string;\n private apiKey: string | undefined;\n\n constructor(config: AgentClientConfig) {\n this.credentials = {\n agentId: config.agentId,\n verifyUrl: config.verifyUrl ?? 'https://astrasync.ai/api/agents/verify-access',\n challengeUrl: config.challengeUrl,\n pdlss: config.pdlss,\n };\n this.apiBaseUrl = config.apiBaseUrl ?? 'https://astrasync.ai/api';\n this.apiKey = config.apiKey;\n }\n\n /**\n * Async factory that validates the API key's account owns the configured\n * ASTRA-id before returning a usable client. Refuses to initialise on\n * mismatch so a stolen ASTRA-id cannot be paired with a valid (different)\n * API key.\n *\n * Set env `ASTRASYNC_SKIP_OWNERSHIP_CHECK=true` to bypass — intended for\n * test environments only.\n */\n static async create(config: AgentClientConfig): Promise<AgentClient> {\n const client = new AgentClient(config);\n\n const skip =\n typeof process !== 'undefined' && process.env?.ASTRASYNC_SKIP_OWNERSHIP_CHECK === 'true';\n if (skip) return client;\n\n if (!config.apiKey) {\n // Without an API key we cannot bind ownership. Surface this as the\n // same refusal so misconfigured clients fail loudly.\n throw new OwnershipMismatchError(config.agentId);\n }\n\n const owned = await client.verifyOwnership();\n if (!owned) throw new OwnershipMismatchError(config.agentId);\n return client;\n }\n\n /**\n * Calls GET /api/agents/:astraId/ownership with the configured API key.\n * Returns true only when the backend confirms this API key's account\n * owns the configured agent.\n */\n private async verifyOwnership(): Promise<boolean> {\n if (!this.apiKey) return false;\n const url = `${this.apiBaseUrl.replace(/\\/+$/, '')}/api/agents/${encodeURIComponent(\n this.credentials.agentId\n )}/ownership`;\n const resp = await fetch(url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n if (!resp.ok) return false;\n const body = (await resp.json().catch(() => null)) as {\n success?: boolean;\n data?: { owned?: boolean };\n } | null;\n return Boolean(body?.data?.owned);\n }\n\n /**\n * Make an HTTP request with AstraSync headers automatically injected.\n */\n async fetch(url: string, options?: FetchOptions): Promise<Response> {\n const { purpose, action, ...fetchOptions } = options ?? {};\n\n // Build credentials with optional overrides\n const creds: AstraSyncCredentials = { ...this.credentials };\n if (purpose) {\n creds.pdlss = {\n ...creds.pdlss,\n purpose: { category: purpose, action },\n };\n }\n\n // Inject AstraSync headers\n const existingHeaders: Record<string, string> = {};\n if (fetchOptions.headers) {\n if (fetchOptions.headers instanceof Headers) {\n fetchOptions.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n } else if (Array.isArray(fetchOptions.headers)) {\n for (const [key, value] of fetchOptions.headers) {\n existingHeaders[key] = value;\n }\n } else {\n Object.assign(existingHeaders, fetchOptions.headers);\n }\n }\n\n const enrichedHeaders = setHttpHeaders(existingHeaders, creds);\n\n return fetch(url, {\n ...fetchOptions,\n headers: enrichedHeaders,\n });\n }\n\n /**\n * Prepare A2A task metadata with AstraSync credentials.\n */\n prepareA2AMetadata(\n task: Record<string, unknown>,\n overrides?: { purpose?: string; action?: string }\n ): Record<string, unknown> {\n const creds = this.buildCredentials(overrides);\n return setA2AMetadata(task, creds);\n }\n\n /**\n * Prepare MCP params with AstraSync _meta.\n */\n prepareMcpMeta(\n params: Record<string, unknown>,\n overrides?: { purpose?: string; action?: string }\n ): Record<string, unknown> {\n const creds = this.buildCredentials(overrides);\n return setMcpMeta(params, creds);\n }\n\n /**\n * Generic: apply credentials to any protocol.\n */\n applyCredentials(\n protocol: ProtocolTransport,\n target: Record<string, unknown>,\n overrides?: { purpose?: string; action?: string }\n ): Record<string, unknown> {\n const creds = this.buildCredentials(overrides);\n return applyCredentials(protocol, target, creds);\n }\n\n private buildCredentials(overrides?: {\n purpose?: string;\n action?: string;\n }): AstraSyncCredentials {\n if (!overrides?.purpose) return this.credentials;\n\n return {\n ...this.credentials,\n pdlss: {\n ...this.credentials.pdlss,\n purpose: { category: overrides.purpose, action: overrides.action },\n },\n };\n }\n}\n","/**\n * ChallengeHandler — Agent-Side Runtime Challenge Responder\n *\n * Handles incoming runtime challenges from AstraSync's verification service.\n * Agents register pending counterparties before initiating contact,\n * then this handler validates and responds to challenges.\n */\n\ninterface ChallengePayload {\n challengeId: string;\n type: string;\n counterpartyId?: string | null;\n counterpartyUrl?: string | null;\n question?: string;\n issuedAt: string;\n expiresAt: string;\n}\n\ninterface ChallengeResponse {\n status: number;\n body: {\n challengeId: string;\n acknowledged: boolean;\n pendingCounterparties: string[];\n respondedAt: string;\n error?: string;\n };\n}\n\ninterface ChallengeHandlerConfig {\n agentId: string;\n}\n\nexport class ChallengeHandler {\n private agentId: string;\n private pendingCounterparties: Set<string> = new Set();\n\n constructor(config: ChallengeHandlerConfig) {\n this.agentId = config.agentId;\n }\n\n /**\n * Register a counterparty as pending (before initiating contact).\n */\n registerPending(counterpartyId: string): void {\n this.pendingCounterparties.add(counterpartyId);\n }\n\n /**\n * Remove a counterparty from pending list (after interaction complete).\n */\n removePending(counterpartyId: string): void {\n this.pendingCounterparties.delete(counterpartyId);\n }\n\n /**\n * Get current pending counterparties list.\n */\n getPendingList(): string[] {\n return [...this.pendingCounterparties];\n }\n\n /**\n * Express middleware for the challenge endpoint.\n * Mount at: app.post('/astrasync/challenge', handler.expressMiddleware())\n */\n expressMiddleware(): (req: { body: unknown }, res: { status: (code: number) => { json: (body: unknown) => void } }) => void {\n return (req, res) => {\n const result = this.handleChallenge(req.body);\n res.status(result.status).json(result.body);\n };\n }\n\n /**\n * Generic handler (framework-agnostic).\n * Returns { status, body } for the caller to send.\n */\n handleChallenge(body: unknown): ChallengeResponse {\n // Validate payload shape\n if (!body || typeof body !== 'object') {\n return {\n status: 400,\n body: {\n challengeId: '',\n acknowledged: false,\n pendingCounterparties: [],\n respondedAt: new Date().toISOString(),\n error: 'Invalid challenge payload',\n },\n };\n }\n\n const payload = body as ChallengePayload;\n\n if (!payload.challengeId || !payload.issuedAt || !payload.expiresAt) {\n return {\n status: 400,\n body: {\n challengeId: payload.challengeId ?? '',\n acknowledged: false,\n pendingCounterparties: [],\n respondedAt: new Date().toISOString(),\n error: 'Missing required challenge fields',\n },\n };\n }\n\n // Check if challenge has expired\n const now = new Date();\n const expiresAt = new Date(payload.expiresAt);\n if (now > expiresAt) {\n return {\n status: 410,\n body: {\n challengeId: payload.challengeId,\n acknowledged: false,\n pendingCounterparties: [],\n respondedAt: now.toISOString(),\n error: 'Challenge has expired',\n },\n };\n }\n\n // Respond with current pending list\n return {\n status: 200,\n body: {\n challengeId: payload.challengeId,\n acknowledged: true,\n pendingCounterparties: this.getPendingList(),\n respondedAt: now.toISOString(),\n },\n };\n }\n}\n","/**\n * PDLSS Formatter — Transport Format Conversion\n *\n * Converts between full PDLSS boundaries and compact transport format\n * used in HTTP headers, A2A metadata, and MCP _meta blocks.\n */\n\nimport type { AstraSyncCredentials } from '../types';\n\n/**\n * Full PDLSS configuration (as returned by the backend).\n */\nexport interface PDLSSConfig {\n purpose?: {\n categories?: string[];\n allowedActions?: string[];\n deniedActions?: string[];\n };\n duration?: {\n maxSessionDuration?: number;\n ttl?: number;\n allowedDays?: number[];\n allowedHours?: { start: number; end: number };\n };\n limits?: {\n autonomousThreshold?: number;\n stepUpThreshold?: number;\n approvalThreshold?: number;\n currency?: string;\n };\n scope?: {\n jurisdictions?: string[];\n resources?: string[];\n resourceTypes?: string[];\n };\n selfInstantiation?: {\n allowed: boolean;\n maxDepth?: number;\n maxSubAgents?: number;\n };\n}\n\n/**\n * Compact transport format (embedded in headers/metadata).\n */\nexport type TransportPDLSS = NonNullable<AstraSyncCredentials['pdlss']>;\n\n/**\n * Convert full PDLSS boundaries into compact transport format.\n * Used by AgentClient when building credential headers/metadata.\n */\nexport function formatPDLSSForTransport(pdlss: PDLSSConfig): TransportPDLSS {\n const transport: TransportPDLSS = {};\n\n // Purpose: pick the primary category and first allowed action\n if (pdlss.purpose?.categories?.length) {\n transport.purpose = {\n category: pdlss.purpose.categories[0],\n action: pdlss.purpose.allowedActions?.[0],\n };\n }\n\n // Duration: use the shorter of maxSessionDuration and ttl\n if (pdlss.duration) {\n const candidates: number[] = [];\n if (pdlss.duration.maxSessionDuration) candidates.push(pdlss.duration.maxSessionDuration);\n if (pdlss.duration.ttl) candidates.push(pdlss.duration.ttl);\n if (candidates.length > 0) {\n transport.duration = { maxSessionDuration: Math.min(...candidates) };\n }\n }\n\n // Scope: use the primary jurisdiction\n if (pdlss.scope?.jurisdictions?.length) {\n transport.scope = { jurisdiction: pdlss.scope.jurisdictions[0] };\n }\n\n return transport;\n}\n\n/**\n * Parse transport format back into full PDLSS config.\n * Used by counterparty-side when receiving credentials.\n */\nexport function parsePDLSSFromTransport(transport: TransportPDLSS): PDLSSConfig {\n const pdlss: PDLSSConfig = {};\n\n if (transport.purpose) {\n pdlss.purpose = {\n categories: [transport.purpose.category],\n allowedActions: transport.purpose.action ? [transport.purpose.action] : undefined,\n };\n }\n\n if (transport.duration) {\n pdlss.duration = {\n maxSessionDuration: transport.duration.maxSessionDuration,\n };\n }\n\n if (transport.scope) {\n pdlss.scope = {\n jurisdictions: transport.scope.jurisdiction ? [transport.scope.jurisdiction] : undefined,\n };\n }\n\n return pdlss;\n}\n","/**\n * Decision Client — Counterparty-Side Decision Recording\n *\n * Helper for counterparties to record their grant/deny decisions\n * back to AstraSync after receiving a verification result.\n */\n\nimport type { GatewayConfig } from '../types';\n\ninterface RecordDecisionParams {\n sessionId: string;\n decision: 'granted' | 'denied';\n reason?: string;\n tokenIssued?: boolean;\n auditId?: string;\n}\n\ninterface RecordDecisionResult {\n recorded: boolean;\n blockchainTxHash?: string;\n}\n\n/**\n * Record a counterparty's grant/deny decision for a verification session.\n * POST to /agents/verify-access/:sessionId/decision\n */\nexport async function recordDecision(\n config: GatewayConfig,\n params: RecordDecisionParams,\n): Promise<RecordDecisionResult> {\n const { sessionId, ...body } = params;\n const baseUrl = config.apiBaseUrl.replace(/\\/$/, '');\n const url = `${baseUrl}/agents/verify-access/${encodeURIComponent(sessionId)}/decision`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n }\n\n if (config.customHeaders) {\n Object.assign(headers, config.customHeaders);\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n throw new Error(\n `Failed to record decision for session ${sessionId}: ${response.status} ${errorText}`,\n );\n }\n\n const result = await response.json();\n\n return {\n recorded: result.recorded ?? true,\n blockchainTxHash: result.blockchainTxHash,\n };\n}\n"],"mappings":"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","names":["recordDecision","result","result","createMiddleware","matchRoute","findRouteConfig","DEFAULT_ROUTES_REFRESH_MS","createMiddleware","coerceString","stripQuery","extractSessionId","readHeader","coerceString","coerceString","coerceNumber","import_node_crypto","claim","import_decode","import_node_crypto","sha256Sync","applyDisclosures","coerceMandateType","coerceString","coerceNumber","readHeader","coerceString","import_mppx","readHeader","import_node_crypto","coerceString","toUnixSeconds","recordDecision","recordDecision"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/access-levels.ts","../src/version.ts","../src/verify.ts","../src/adapters/express.ts","../src/transport/http.ts","../src/pdlss-pre-check.ts","../src/adapters/nextjs.ts","../src/adapters/sdk.ts","../src/transport/index.ts","../src/transport/a2a.ts","../src/transport/mcp.ts","../src/transport/purpose-mapping.ts","../src/transport/transaction-value.ts","../src/transport/rfc9421.ts","../src/transport/rfc9421-verify.ts","../src/transport/ucp.ts","../src/transport/acp.ts","../src/transport/vi.ts","../src/transport/stripe-webhook.ts","../src/transport/constraint-eval.ts","../src/transport/identity-binding.ts","../src/transport/ap2.ts","../src/transport/ap2-verify.ts","../src/transport/acp-verify.ts","../src/transport/mpp.ts","../src/transport/mpp-verify.ts","../src/transport/x402.ts","../src/transport/vi-verify.ts","../src/transport/commerce-pipeline.ts","../src/transport/extractor-registry.ts","../src/transport/registry/visa.ts","../src/transport/registry/mastercard.ts","../src/transport/registry/web-bot-auth.ts","../src/transport/mcp-server.ts","../src/adapters/mcp.ts","../src/registration/errors.ts","../src/registration/api.ts","../src/registration/guidance.ts","../src/agent/index.ts","../src/agent/errors.ts","../src/agent/client.ts","../src/agent/challenge-handler.ts","../src/agent/pdlss-formatter.ts","../src/agent/decision-client.ts"],"sourcesContent":["/**\n * AstraSync Universal Verification Gateway\n *\n * A single verification library for any system to verify AI agents.\n * One codebase, multiple deployment targets.\n *\n * @example\n * ```typescript\n * import { verify, extractCredentials } from '@astrasyncai/verification-gateway';\n *\n * const credentials = extractCredentials(request.headers);\n * const result = await verify(config, { credentials, purpose: 'data-access' });\n *\n * if (result.identityVerified && result.policyAllowed && result.accessLevel !== 'none') {\n * // Grant access based on result.accessLevel\n * }\n *\n * // Or map to HTTP status codes directly:\n * if (!result.identityVerified) return res.status(401).json({ ... }); // re-auth\n * if (!result.policyAllowed) return res.status(403).json({ ... }); // step up / update PDLSS\n * ```\n *\n * @packageDocumentation\n */\n\n// Core types\nexport type {\n TrustLevel,\n AccessLevel,\n CounterpartyType,\n AgentCredentials,\n GatewayConfig,\n VerifiedAgent,\n VerifiedDeveloper,\n VerifiedOrganization,\n PDLSSInfo,\n GuidanceInfo,\n VerificationResult,\n VerificationRequest,\n RouteAccessConfig,\n ExpressMiddlewareOptions,\n NextJsMiddlewareOptions,\n SDKOptions,\n CommerceShieldProps,\n // Handshake Protocol v10 types\n TokenGuidance,\n RuntimeChallengeResult,\n EnhancedVerificationResult,\n AstraSyncCredentials,\n ProtocolTransport,\n} from './types';\n\n// Access level utilities\nexport {\n ACCESS_LEVEL_HIERARCHY,\n ACCESS_LEVEL_DESCRIPTIONS,\n DEFAULT_TRUST_THRESHOLDS,\n TRUST_LEVEL_RANGES,\n getTrustLevel,\n hasMinimumAccess,\n getAccessLevelForScore,\n determineAccessLevel,\n getCapabilities,\n} from './access-levels';\n\nexport type { AccessCapabilities } from './access-levels';\n\n// Core verification functions\nexport { verify, quickVerify, extractCredentials, hasCredentials, clearCache } from './verify';\n\n// Re-export adapters for convenience (tree-shakeable)\nexport * as express from './adapters/express';\nexport * as nextjs from './adapters/nextjs';\nexport * as sdk from './adapters/sdk';\n\n// Cross-protocol transport adapters\nexport * as transport from './transport';\n\n// Round-16 — flat re-exports of MCP bridge helpers so consumers using\n// `moduleResolution: \"node\"` can import without the subpath form (subpaths\n// `/mcp`, `/transport` require node16 / nodenext / bundler resolution).\nexport { createMcpMiddleware } from './adapters/mcp';\nexport type { McpMiddlewareOptions } from './adapters/mcp';\nexport { extractMcpCredentials, setMcpMeta } from './transport/mcp';\n\n// Round-17 — flat re-exports of the registration API so consumers using\n// `moduleResolution: \"node\"` (e.g. apps/mcp-server) can import without the\n// `/registration` subpath form. Same pattern as the Round-16 MCP re-exports.\n// Round-18 (B3b) — `buildGuidance` joins the surface so partner wrappers can\n// produce the credentials-required envelope without inlining the five-step\n// boilerplate.\nexport {\n AstraSync,\n AstraSyncError,\n AuthenticationError,\n KYDRequiredError,\n RegistrationDeniedError,\n RegistrationExpiredError,\n RegistrationTimeoutError,\n buildGuidance,\n} from './registration';\nexport type {\n AstraSyncConfig,\n RegisterOptions,\n RegisterResult,\n WaitForApprovalOptions,\n PendingRegistrationResponse,\n PollRegistrationResult,\n RegistrationResponse,\n AgentRecord,\n VerifyResponse,\n HealthResponse,\n PDLSSConfig,\n PDLSSPurpose,\n PDLSSDuration,\n PDLSSLimits,\n PDLSSScope,\n PDLSSSelfInstantiation,\n ModelConfig,\n FrameworkConfig,\n AgentProtocol,\n GuidanceEnvelope,\n BuildGuidanceParams,\n} from './registration';\n\n// Agent-side SDK\nexport * as agent from './agent';\nexport { AgentClient } from './agent/client';\nexport { ChallengeHandler } from './agent/challenge-handler';\nexport { recordDecision } from './agent/decision-client';\n\n// Version\nexport const VERSION = '2.0.0';\n","/**\n * AstraSync Universal Verification Gateway - Access Level Definitions\n *\n * Defines the hierarchy and capabilities of each access level.\n *\n * v2.3.9 (defect #30): renamed `'guidance'` band → `'restricted'`. See\n * `types.ts` AccessLevel for the rationale (value-name collision with the\n * `guidance: {...}` help-payload object on VerificationResult).\n */\n\nimport type { AccessLevel, TrustLevel } from './types';\n\n/**\n * Access level hierarchy (higher number = more access)\n */\nexport const ACCESS_LEVEL_HIERARCHY: Record<AccessLevel, number> = {\n none: 0,\n restricted: 1,\n 'read-only': 2,\n standard: 3,\n full: 4,\n internal: 5,\n};\n\n/**\n * Access level descriptions for UI\n */\nexport const ACCESS_LEVEL_DESCRIPTIONS: Record<AccessLevel, string> = {\n none: 'No access - credentials required',\n restricted: 'Restricted access - registration prompt only',\n 'read-only': 'Read-only access - can browse but not modify',\n standard: 'Standard access - normal operations per PDLSS policy',\n full: 'Full access - all operations for high-trust agents',\n internal: 'Internal access - organization member privileges',\n};\n\n/**\n * Default trust score thresholds for access levels\n */\nexport const DEFAULT_TRUST_THRESHOLDS: Record<AccessLevel, number> = {\n none: 0,\n restricted: 0,\n 'read-only': 20,\n standard: 40,\n full: 70,\n internal: 0, // Internal is based on org membership, not score\n};\n\n/**\n * Trust level score ranges\n */\nexport const TRUST_LEVEL_RANGES: Record<TrustLevel, { min: number; max: number }> = {\n BRONZE: { min: 0, max: 39 },\n SILVER: { min: 40, max: 59 },\n GOLD: { min: 60, max: 79 },\n PLATINUM: { min: 80, max: 100 },\n};\n\n/**\n * Determine trust level from score\n */\nexport function getTrustLevel(score: number): TrustLevel {\n if (score >= 80) return 'PLATINUM';\n if (score >= 60) return 'GOLD';\n if (score >= 40) return 'SILVER';\n return 'BRONZE';\n}\n\n/**\n * Check if access level A is greater than or equal to access level B\n */\nexport function hasMinimumAccess(actual: AccessLevel, required: AccessLevel): boolean {\n return ACCESS_LEVEL_HIERARCHY[actual] >= ACCESS_LEVEL_HIERARCHY[required];\n}\n\n/**\n * Get the highest access level for a given trust score\n */\nexport function getAccessLevelForScore(\n trustScore: number,\n thresholds: Record<AccessLevel, number> = DEFAULT_TRUST_THRESHOLDS\n): AccessLevel {\n if (trustScore >= thresholds.full) return 'full';\n if (trustScore >= thresholds.standard) return 'standard';\n if (trustScore >= thresholds['read-only']) return 'read-only';\n return 'restricted';\n}\n\n/**\n * Determine access level from verification result.\n *\n * v2.3.9 (defect #30): unverified callers now return `'none'` (was\n * `'guidance'`). Denials grant zero — never a positive band.\n */\nexport function determineAccessLevel(\n verified: boolean,\n trustScore: number,\n isOrgMember: boolean,\n customThresholds?: Partial<Record<AccessLevel, number>>\n): AccessLevel {\n if (!verified) {\n return 'none';\n }\n\n if (isOrgMember) {\n return 'internal';\n }\n\n const thresholds = {\n ...DEFAULT_TRUST_THRESHOLDS,\n ...customThresholds,\n };\n\n return getAccessLevelForScore(trustScore, thresholds);\n}\n\n/**\n * Access capabilities per level\n */\nexport interface AccessCapabilities {\n canRead: boolean;\n canWrite: boolean;\n canDelete: boolean;\n canAdmin: boolean;\n canAccessInternal: boolean;\n maxTransactionValue?: number;\n allowedPurposes?: string[];\n}\n\n/**\n * Get capabilities for an access level\n */\nexport function getCapabilities(accessLevel: AccessLevel): AccessCapabilities {\n switch (accessLevel) {\n case 'none':\n return {\n canRead: false,\n canWrite: false,\n canDelete: false,\n canAdmin: false,\n canAccessInternal: false,\n };\n case 'restricted':\n return {\n canRead: false,\n canWrite: false,\n canDelete: false,\n canAdmin: false,\n canAccessInternal: false,\n };\n case 'read-only':\n return {\n canRead: true,\n canWrite: false,\n canDelete: false,\n canAdmin: false,\n canAccessInternal: false,\n };\n case 'standard':\n return {\n canRead: true,\n canWrite: true,\n canDelete: false,\n canAdmin: false,\n canAccessInternal: false,\n };\n case 'full':\n return {\n canRead: true,\n canWrite: true,\n canDelete: true,\n canAdmin: false,\n canAccessInternal: false,\n };\n case 'internal':\n return {\n canRead: true,\n canWrite: true,\n canDelete: true,\n canAdmin: true,\n canAccessInternal: true,\n };\n default:\n return {\n canRead: false,\n canWrite: false,\n canDelete: false,\n canAdmin: false,\n canAccessInternal: false,\n };\n }\n}\n","/**\n * Round-13 (F14 closure / R13-7): single source-of-truth for the SDK's\n * package version emitted on verify-access bodies (and any future\n * telemetry). Bumped alongside `package.json#version` on every release.\n *\n * Why a constant rather than `import pkg from '../package.json'`:\n * - `tsconfig.json` sets `rootDir: ./src`; importing the sibling\n * package.json fails the build with \"outside rootDir\".\n * - Build-time string replacement (tsup `define`, esbuild banner, etc.)\n * adds toolchain coupling for a trivial gain.\n * - Embedded readonly constant works in every environment (Node, browser,\n * bundlers, Deno) without runtime fs / network access.\n *\n * Release discipline: a CI lint can grep `package.json#version` against\n * this constant if the two ever diverge in the wild. Round-13 manual bump\n * is fine — bumping both in the release-ceremony commit keeps them\n * lockstep.\n */\nexport const SDK_VERSION = '2.4.10';\n","/**\n * AstraSync Universal Verification Gateway - Core Verification Logic\n *\n * This module handles the core verification logic, calling the AstraSync API\n * and processing the response into a standardized VerificationResult.\n */\n\nimport type {\n GatewayConfig,\n AgentCredentials,\n VerificationRequest,\n VerificationResult,\n VerifiedAgent,\n VerifiedDeveloper,\n VerifiedOrganization,\n GuidanceInfo,\n AccessLevel,\n EnhancedVerificationResult,\n TokenGuidance,\n RuntimeChallengeResult,\n} from './types';\nimport { getTrustLevel, ACCESS_LEVEL_HIERARCHY } from './access-levels';\nimport { SDK_VERSION } from './version';\n\n/**\n * Default configuration values\n *\n * apiBaseUrl matches the OpenAPI authoritative server (https://astrasync.ai/api\n * for prod, https://staging.astrasync.ai/api for staging). Always include the\n * /api path prefix when overriding — registration / docs URLs are derived by\n * stripping it.\n */\nconst DEFAULT_CONFIG: Partial<GatewayConfig> = {\n apiBaseUrl: 'https://astrasync.ai/api',\n // v2.3.9 (defect #30): default for unconfigured callers is `'none'` (no\n // access). Pre-rename this defaulted to `'guidance'`, which combined with\n // a route gated at `'guidance'` to silently let unverified traffic\n // through (`hasMinimumAccess('guidance', 'guidance') === true`).\n defaultAccessLevel: 'none',\n // minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.\n // Round-18.5 F4: cacheTtl deliberately unset. When undefined, cacheResult\n // applies the split default (60s autonomous / 300s step-up). When the\n // caller sets cacheTtl explicitly, that value is honoured uniformly.\n // Set cacheTtl: 0 to disable caching entirely.\n debug: false,\n};\n\n/**\n * Init self-test state. Fires once per process on first verify() call to warn\n * if apiBaseUrl is pointing at the wrong host (e.g. a marketing site that\n * 200s with text/html instead of the API).\n */\nlet initCheckPerformed = false;\n\n/** One-shot guard for v2.3.0 deprecation warning. */\nlet deprecationWarningShown = false;\n\nasync function performInitCheck(apiBaseUrl: string, debug?: boolean): Promise<void> {\n initCheckPerformed = true;\n try {\n const probeUrl = `${apiBaseUrl}/agents/verify-access`;\n // HEAD mirrors GET semantics (running the full request pipeline without a\n // body) so the response carries the same content-type the marketing 404\n // would return. OPTIONS often gets short-circuited by CORS-preflight\n // handlers and returns no content-type, defeating the check.\n const response = await fetch(probeUrl, { method: 'HEAD' });\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.startsWith('text/html')) {\n console.warn(\n `[VerificationGateway] apiBaseUrl '${apiBaseUrl}' returned HTML (content-type: ${contentType}). ` +\n `This usually means apiBaseUrl is pointing at a marketing site instead of the API. ` +\n `Expected: 'https://astrasync.ai/api' (prod) or 'https://staging.astrasync.ai/api' (staging). ` +\n `Set disableInitChecks: true on GatewayConfig to silence this warning.`\n );\n } else if (debug) {\n console.log(\n `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`\n );\n }\n } catch (err) {\n if (debug) {\n console.log(`[VerificationGateway] init check failed (non-blocking): ${String(err)}`);\n }\n }\n}\n\n/**\n * Simple in-memory cache for verification results\n */\nconst verificationCache = new Map<string, { result: VerificationResult; expiresAt: number }>();\n\n/**\n * Generate cache key from the full request shape.\n *\n * Round-18.5 F4: pre-fix the key was credentials-only (`astraId-apiKey-jwt`),\n * which silently returned the cached result of a prior call even when the\n * subsequent call's purpose/action/counterparty/etc. differed. That was a\n * security gap — a warm cache could serve an allow verdict for a purpose the\n * agent hadn't actually been authorised for. Key now includes every field\n * that affects the backend verdict.\n *\n * MAINTAIN: when adding a field to VerificationRequest that affects the\n * backend verdict, add it to this key. Fields that don't affect verdict\n * (e.g. requestId, timestamps, sdkVersion) don't belong here — including\n * them would needlessly thrash the cache for repeated identical requests.\n */\nfunction getCacheKey(request: VerificationRequest): string {\n const c = request.credentials;\n return [\n c.astraId || '',\n c.apiKey || '',\n c.jwt || '',\n request.purpose || '',\n request.action || '',\n request.resourceType || '',\n request.resource || '',\n request.jurisdiction || '',\n request.transactionValue ?? '',\n request.currency || '',\n request.counterpartyUrl || '',\n request.counterpartyType || '',\n request.isSubAgentRequest ? '1' : '0',\n request.parentAgentId || '',\n request.subAgentDepth ?? '',\n ].join('|');\n}\n\n/**\n * Check if cached result is still valid\n */\nfunction getCachedResult(request: VerificationRequest): VerificationResult | null {\n const key = getCacheKey(request);\n const cached = verificationCache.get(key);\n\n if (cached && cached.expiresAt > Date.now()) {\n return cached.result;\n }\n\n if (cached) {\n verificationCache.delete(key);\n }\n\n return null;\n}\n\n/**\n * Cache a verification result.\n *\n * Round-18.5 F4: TTL splits by step-up status when the caller hasn't pinned\n * `configuredTtl` explicitly. Autonomous verdicts cache for 60s (faster\n * policy-update propagation, better security posture); step-up verdicts cache\n * for 300s (matches human-paced approval cycles, prevents thrashing during\n * the user-action window). When `configuredTtl` is set (truthy positive\n * number), it's honoured uniformly for back-compat with partners pinning a\n * specific TTL today.\n */\nconst DEFAULT_AUTONOMOUS_TTL_SECONDS = 60;\nconst DEFAULT_STEP_UP_TTL_SECONDS = 300;\n\nfunction cacheResult(\n request: VerificationRequest,\n result: VerificationResult,\n configuredTtl: number | undefined\n): void {\n const ttlSeconds =\n configuredTtl && configuredTtl > 0\n ? configuredTtl\n : result.requiresStepUp\n ? DEFAULT_STEP_UP_TTL_SECONDS\n : DEFAULT_AUTONOMOUS_TTL_SECONDS;\n const key = getCacheKey(request);\n verificationCache.set(key, {\n result,\n expiresAt: Date.now() + ttlSeconds * 1000,\n });\n}\n\n/**\n * Clear the verification cache\n */\nexport function clearCache(): void {\n verificationCache.clear();\n}\n\n/**\n * Extract agent credentials from various sources\n */\nexport function extractCredentials(\n headers: Record<string, string | string[] | undefined>,\n query?: Record<string, string | undefined>\n): AgentCredentials {\n const credentials: AgentCredentials = {};\n\n // Check for ASTRA-ID in headers (case-insensitive). Accepts the historical\n // X-Astra-Id name plus the X-Astra-AgentId / x-astra-agent-id alias the\n // partner asked for in #9a — both surface the same field.\n const astraIdHeader =\n headers['x-astra-id'] ||\n headers['X-Astra-Id'] ||\n headers['X-ASTRA-ID'] ||\n headers['x-astra-agentid'] ||\n headers['X-Astra-AgentId'] ||\n headers['x-astra-agent-id'] ||\n headers['X-Astra-Agent-Id'] ||\n headers['X-ASTRA-AGENT-ID'];\n if (astraIdHeader) {\n credentials.astraId = Array.isArray(astraIdHeader) ? astraIdHeader[0] : astraIdHeader;\n }\n\n // Check for API key in headers\n const apiKeyHeader = headers['x-api-key'] || headers['X-Api-Key'] || headers['X-API-KEY'];\n if (apiKeyHeader) {\n credentials.apiKey = Array.isArray(apiKeyHeader) ? apiKeyHeader[0] : apiKeyHeader;\n }\n\n // Check Authorization header for Bearer token\n const authHeader = headers['authorization'] || headers['Authorization'];\n if (authHeader) {\n const authValue = Array.isArray(authHeader) ? authHeader[0] : authHeader;\n credentials.authorizationHeader = authValue;\n\n if (authValue.startsWith('Bearer ')) {\n credentials.jwt = authValue.slice(7);\n }\n }\n\n // Check query parameters as fallback\n if (query) {\n if (query.astraId && !credentials.astraId) {\n credentials.astraId = query.astraId;\n }\n if (query.apiKey && !credentials.apiKey) {\n credentials.apiKey = query.apiKey;\n }\n }\n\n return credentials;\n}\n\n/**\n * Check if credentials are present\n */\nexport function hasCredentials(credentials: AgentCredentials): boolean {\n return !!(credentials.astraId || credentials.apiKey || credentials.jwt);\n}\n\n/**\n * Source of a synthesised guidance response. Round-10 split — the\n * `'no_credentials'` shape is the original (caller has no AstraSync\n * credentials, suggest registration). The `'api_error'` shape is for when\n * the verify-access HTTP call itself failed (5xx, network, etc.) — DON'T\n * tell a verified-but-currently-blocked partner to \"register your agent\".\n */\ntype GuidanceSource = 'no_credentials' | 'api_error';\n\n/**\n * Create guidance response for unverified agents or for API-error fallback.\n *\n * Round-10 (#47, O5): split source so the `register your agent` template\n * doesn't fire on transient backend failures. Also threads `correlationId`\n * through so adapter `onDenied` handlers can surface it on the merchant's\n * response body for log correlation.\n */\nfunction createGuidanceResponse(\n config: GatewayConfig,\n reason?: string,\n options: { source?: GuidanceSource; correlationId?: string } = {}\n): VerificationResult {\n const source = options.source ?? 'no_credentials';\n const isApiError = source === 'api_error';\n\n const guidance: GuidanceInfo = isApiError\n ? {\n message:\n 'Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.',\n registrationUrl: `${config.apiBaseUrl.replace('/api', '')}/register`,\n documentationUrl: `${config.apiBaseUrl.replace('/api', '')}/docs/agent-access`,\n steps: [\n 'Retry the request with exponential backoff',\n 'If failures persist, share the correlationId with support',\n ],\n }\n : {\n message:\n 'This service verifies AI agents before granting access. Please register your agent with AstraSync.',\n registrationUrl: `${config.apiBaseUrl.replace('/api', '')}/register`,\n documentationUrl: `${config.apiBaseUrl.replace('/api', '')}/docs/agent-access`,\n steps: [\n 'Register for an AstraSync account',\n 'Create and register your agent',\n 'Add your ASTRA-ID to request headers',\n 'Retry your request',\n ],\n };\n\n return {\n // Round-18 G4: createGuidanceResponse fires for unverified-agent path or\n // API-error fallback. Identity is not verified (no agent resolved);\n // policy is not evaluated (we never reached the gate).\n identityVerified: false,\n policyAllowed: false,\n // v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.\n // Adapters additionally short-circuit on `!identityVerified ||\n // !policyAllowed` before the gate check, but the access level still has\n // to be honest at the data layer so downstream consumers (SDK adapters\n // in other languages, custom integrations) inherit the correct\n // semantics.\n accessLevel: 'none',\n guidance,\n denialReasons: reason ? [reason] : ['No valid agent credentials provided'],\n // Round-10 (#47, O5): on API-error fallback, surface a typed failure so\n // partners (and their custom onDenied handlers) can branch on\n // dimension. Without this, the synthesised stub was indistinguishable\n // from a real policy deny.\n failures: isApiError\n ? [\n {\n dimension: 'verify_access.api_error',\n message: reason ?? 'Verification temporarily unavailable',\n guidance: guidance.message,\n },\n ]\n : undefined,\n correlationId: options.correlationId,\n verifiedAt: new Date(),\n };\n}\n\n/**\n * Call the AstraSync verify-access API\n */\nasync function callVerifyAccessAPI(\n config: GatewayConfig,\n request: VerificationRequest\n): Promise<{\n success: boolean;\n access?: {\n allowed: boolean;\n /**\n * Server-decided access level. Read verbatim — do NOT remap client-side.\n * The server resolves this from endpoint policy + agent trust score using\n * the canonical thresholds (see backend `apps/backend/src/utils/access-levels.ts`).\n */\n accessLevel?: AccessLevel;\n reason?: string;\n /**\n * Aggregated denial failures (v2.9.8+). Empty / absent when allowed.\n * Each entry is `{ dimension, message, guidance? }` — see\n * `AccessFailure` for the contract.\n */\n failures?: Array<{ dimension: string; message: string; guidance?: string }>;\n requiresStepUp?: boolean;\n requiresApproval?: boolean;\n appliedPolicy?: {\n boundaryName: string;\n policyVersion: string;\n };\n counterparty?: {\n id: string;\n name: string;\n trustScoreRequirement: number;\n };\n };\n agent?: {\n kyaAgentId: string;\n astraId: string;\n name: string;\n trustScore: number;\n trustLevel: string;\n agentStatus: string;\n blockchainStatus: string;\n };\n developer?: {\n kyaOwnerId: string;\n fullName: string;\n email: string;\n identityVerified: boolean;\n trustScore: number;\n };\n organization?: {\n name: string;\n verified: boolean;\n trustScore: number;\n };\n /**\n * Structured explanation of the verification decision. Tells the merchant\n * WHY (id verified? challenge passed? request within PDLSS? trust score?)\n * without exposing thresholds, scope lists, or other-tenant counterparty\n * membership. Empty `attestations` unless the endpoint's access policy\n * declared `required_attestations`.\n */\n verificationContext?: {\n idVerified: boolean;\n runtimeChallenge: {\n status: 'passed' | 'skipped' | 'failed' | 'timeout' | 'not_supported';\n checkedAt: string | null;\n };\n pdlssCheck: {\n result: 'within' | 'exceeded' | 'denied' | 'not_evaluated';\n purpose: 'approved' | 'denied';\n scope: 'approved' | 'denied';\n };\n dynamicTrustScore: number;\n attestations: Array<{\n type: string;\n status: 'passed' | 'failed';\n validUntil?: string;\n proofType: 'reference' | 'zkp';\n proof: string;\n }>;\n };\n error?: string;\n /**\n * Round-10 (#47, O5): when the verify-access server response carries a\n * correlationId on an error envelope, propagate it so the SDK can thread\n * it through createGuidanceResponse → adapter onDenied → merchant body.\n */\n correlationId?: string;\n}> {\n const { credentials, ...requestData } = request;\n\n // Build the request body. agentId is omitted when not provided so the\n // server treats it as an anonymous canonical-flow call (Branch A/B/C).\n const body: Record<string, unknown> = {\n ...(credentials.astraId && { agentId: credentials.astraId }),\n purpose: requestData.purpose || 'general',\n };\n\n // Add optional fields\n if (requestData.action) body.action = requestData.action;\n if (requestData.resourceType) body.resourceType = requestData.resourceType;\n if (requestData.resource) body.resource = requestData.resource;\n if (requestData.jurisdiction) body.jurisdiction = requestData.jurisdiction;\n if (requestData.transactionValue) body.transactionValue = requestData.transactionValue;\n if (requestData.currency) body.currency = requestData.currency;\n if (requestData.isSubAgentRequest) body.isSubAgentRequest = requestData.isSubAgentRequest;\n if (requestData.parentAgentId) body.parentAgentId = requestData.parentAgentId;\n if (requestData.subAgentDepth !== undefined) body.subAgentDepth = requestData.subAgentDepth;\n // Handshake Protocol v10 additions\n if (requestData.enableRuntimeChallenge)\n body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;\n if (requestData.createSession) body.createSession = requestData.createSession;\n if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;\n if (requestData.counterpartyType) body.counterpartyType = requestData.counterpartyType;\n if (requestData.counterpartyUrl) body.counterpartyUrl = requestData.counterpartyUrl;\n if (config.counterpartyId) body.counterpartyId = config.counterpartyId;\n if (requestData.runtimeChallengeOptions)\n body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;\n // Round-12 (F19): transport-vs-intent separation. MCP middleware sets\n // this to 'mcp'; non-MCP callers leave it unset.\n if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;\n\n // Round-13 (F14 closure / R13-7): emit the SDK package version on every\n // verify-access body so the backend can auto-populate `kya_counterparty.\n // sdk_version` for the calling endpoint. Body field (not User-Agent\n // header) is the canonical channel — works in Node, browser, behind\n // Cloudflare, and across SDK bundlers without environment-specific\n // header gymnastics. Backend's `validation.ts:verifyAccessSchema`\n // accepts the semver regex; the auto-pop logic is forward-only.\n body.sdkVersion = SDK_VERSION;\n\n // Forward caller metadata when present. Merges the legacy top-level\n // clientIp/userAgent into the nested block for backward compatibility.\n if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {\n const meta = {\n ...(requestData.clientIp && { sourceIp: requestData.clientIp }),\n ...(requestData.userAgent && { userAgent: requestData.userAgent }),\n ...requestData.callerMetadata,\n };\n if (Object.keys(meta).length > 0) body.callerMetadata = meta;\n }\n\n // Build headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...config.customHeaders,\n };\n\n // verify-access requires authentication. The backend's authenticate middleware\n // accepts either a JWT or an API key (starts with kya_) via `Authorization: Bearer <token>`.\n // Credential-supplied auth header (e.g. the agent's own token) takes priority.\n if (credentials.authorizationHeader) {\n headers['Authorization'] = credentials.authorizationHeader;\n } else if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n }\n // Legacy header kept for compatibility with any middleware that reads it directly.\n if (config.apiKey) {\n headers['X-API-Key'] = config.apiKey;\n }\n\n try {\n const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n const data = await response.json();\n\n // v2.3.8 (defect #29): treat 410 Gone as a deterministic deactivated-endpoint\n // signal. Older SDKs may treat any non-2xx as transient and retry; v2.3.8+\n // surfaces it as a structured denial with `reason: 'endpoint_deactivated'`\n // so callers can distinguish \"endpoint gone\" from \"endpoint denied this\".\n if (response.status === 410) {\n return {\n success: true,\n access: {\n allowed: false,\n accessLevel: 'none',\n reason: 'endpoint_deactivated',\n failures: [\n {\n dimension: 'endpoint.deactivated',\n message:\n typeof data?.message === 'string' ? data.message : 'Endpoint has been deactivated',\n guidance:\n typeof data?.guidance === 'string'\n ? data.guidance\n : 'Reactivate via POST /api/endpoints/{id}/reactivate, or update the URL on the calling agent.',\n },\n ],\n },\n };\n }\n\n if (!response.ok) {\n // Round-10 (#47, O5): propagate correlationId on the error path too if\n // the server happened to include one (some 5xx error envelopes carry\n // it). Lets the SDK pass it through to the adapter onDenied handler.\n return {\n success: false,\n error: data.message || data.error || `API returned ${response.status}`,\n correlationId: typeof data?.correlationId === 'string' ? data.correlationId : undefined,\n };\n }\n\n return data;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return {\n success: false,\n error: `Failed to call verify-access API: ${message}`,\n };\n }\n}\n\n/**\n * Main verification function\n */\nexport async function verify(\n config: GatewayConfig,\n request: VerificationRequest\n): Promise<VerificationResult> {\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\n\n // One-time init self-test — fire-and-forget, never blocks verify().\n if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {\n void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug);\n }\n\n // Deprecation warning for v2.3.0 removed config fields. Fires once per process.\n if (\n !deprecationWarningShown &&\n (config.minTrustScore !== undefined || config.minTrustScoreForFull !== undefined)\n ) {\n deprecationWarningShown = true;\n console.warn(\n '[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 ' +\n 'and have no effect. Server is now the single source of truth for access-level decisions ' +\n '(the SDK reads access.accessLevel from the verify-access response). To gate access ' +\n \"to an endpoint, configure the endpoint's trust_score_requirement server-side.\"\n );\n }\n\n // v2.3.0: anonymous traffic no longer short-circuits here. We forward the\n // request to the server with no agentId; the server applies the endpoint's\n // unverifiedAgentPolicy and returns advisory. createGuidanceResponse remains\n // as the offline fallback if the API itself fails (handled below).\n\n // Check cache first. Round-18.5 F4: caching on unless caller explicitly\n // sets cacheTtl: 0 to disable. Undefined falls through to the split default\n // (60s autonomous / 300s step-up) at cacheResult write time.\n if (mergedConfig.cacheTtl !== 0) {\n const cached = getCachedResult(request);\n if (cached) {\n if (mergedConfig.debug) {\n console.log('[VerificationGateway] Returning cached result');\n }\n return cached;\n }\n }\n\n // Inject counterparty info from config if not already set in request\n const enrichedRequest = { ...request };\n if (!enrichedRequest.counterpartyUrl && mergedConfig.counterpartyUrl) {\n enrichedRequest.counterpartyUrl = mergedConfig.counterpartyUrl;\n }\n if (!enrichedRequest.counterpartyType && mergedConfig.counterpartyType) {\n enrichedRequest.counterpartyType = mergedConfig.counterpartyType;\n }\n\n // Call the API\n if (mergedConfig.debug) {\n console.log('[VerificationGateway] Calling verify-access API');\n }\n\n const apiResponse = await callVerifyAccessAPI(mergedConfig, enrichedRequest);\n\n // Handle API errors\n if (!apiResponse.success) {\n // Round-10 (#47, O5): distinguish API errors from missing-credentials.\n // The previous default tagged any failure with the \"register your\n // agent\" template, which is misleading to a verified partner whose\n // verify-access call hit a 500. The `api_error` source surfaces a\n // typed `verify_access.api_error` failure entry instead.\n return createGuidanceResponse(mergedConfig, apiResponse.error, {\n source: 'api_error',\n correlationId: (apiResponse as { correlationId?: string }).correlationId,\n });\n }\n\n // Check access result\n if (!apiResponse.access?.allowed) {\n // v2.9.8 (defect M1): aggregated failures across every gate that\n // denied. Surface them on the result so the integrator can see every\n // blocker in one go instead of the previous fail-fast cascade.\n const aggregatedFailures = (apiResponse.access as Record<string, unknown> | undefined)\n ?.failures as Array<{ dimension: string; message: string; guidance?: string }> | undefined;\n // Round-18 G4: backend denied access (PDLSS or other gate); identity status\n // depends on whether the backend resolved the caller. Read from\n // verificationContext.idVerified; default false if absent (anonymous or\n // identity-fail paths land here too). policyAllowed is false by definition\n // in this branch (apiResponse.access.allowed === false).\n const idVerifiedFromBackend =\n (apiResponse.verificationContext as { idVerified?: boolean } | undefined)?.idVerified ===\n true;\n const result: EnhancedVerificationResult = {\n identityVerified: idVerifiedFromBackend,\n policyAllowed: false,\n // v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.\n // Pre-rename this hardcoded `'guidance'`, which conflated with the\n // colocated `guidance: {...}` help-payload object below and let\n // denied requests pass any route gated at `'guidance'` because\n // `hasMinimumAccess('guidance', 'guidance') === true`. Adapters now\n // ALSO short-circuit on `!identityVerified || !policyAllowed` before\n // the gate check — belt-and-braces.\n accessLevel: 'none',\n denialReasons:\n aggregatedFailures && aggregatedFailures.length > 0\n ? aggregatedFailures.map((f) => f.message)\n : apiResponse.access?.reason\n ? [apiResponse.access.reason]\n : ['Access denied'],\n failures: aggregatedFailures,\n requiresStepUp: apiResponse.access?.requiresStepUp,\n requiresApproval: apiResponse.access?.requiresApproval,\n guidance: {\n message: apiResponse.access?.reason || 'Access denied by PDLSS policy',\n registrationUrl: `${mergedConfig.apiBaseUrl?.replace('/api', '')}/register`,\n documentationUrl: `${mergedConfig.apiBaseUrl?.replace('/api', '')}/docs/pdlss`,\n },\n verifiedAt: new Date(),\n // Extract sessionId so decisions can be recorded for denials too\n sessionId: (apiResponse as Record<string, unknown>).sessionId as string | undefined,\n // v2.3.10 (defect #34, round-4): anonymous traffic has no session →\n // correlationId is the linking key for paired local_override events.\n correlationId: (apiResponse as Record<string, unknown>).correlationId as string | undefined,\n recommendation: (apiResponse as Record<string, unknown>)\n .recommendation as EnhancedVerificationResult['recommendation'],\n recommendationReasons: (apiResponse as Record<string, unknown>).recommendationReasons as\n | string[]\n | undefined,\n };\n\n return result;\n }\n\n // Build successful result\n const agent: VerifiedAgent | undefined = apiResponse.agent\n ? {\n astraId: apiResponse.agent.astraId,\n name: apiResponse.agent.name,\n trustScore: apiResponse.agent.trustScore,\n trustLevel: getTrustLevel(apiResponse.agent.trustScore),\n blockchainVerified: apiResponse.agent.blockchainStatus === 'verified',\n status: apiResponse.agent.agentStatus as VerifiedAgent['status'],\n }\n : undefined;\n\n const developer: VerifiedDeveloper | undefined = apiResponse.developer\n ? {\n astradId: apiResponse.developer.kyaOwnerId,\n name: apiResponse.developer.fullName,\n trustScore: apiResponse.developer.trustScore || 0,\n verified: apiResponse.developer.identityVerified,\n }\n : undefined;\n\n const organization: VerifiedOrganization | undefined = apiResponse.organization\n ? {\n name: apiResponse.organization.name,\n verified: apiResponse.organization.verified,\n trustScore: apiResponse.organization.trustScore,\n }\n : undefined;\n\n // Verification context — structured \"why\" the merchant gets in v2.2.4+.\n // Carries appliedPolicy (no UUIDs), pdlssCheck summary, dynamic trust score,\n // and policy-driven attestations. Replaces the old over-sharing `pdlss` block.\n const verificationContext = apiResponse.verificationContext;\n\n // Server is the single source of truth for access level. SDK reads\n // apiResponse.access.accessLevel verbatim — no client-side trust-score remap.\n // Fallback to 'standard' if the server response is missing the field (older\n // backend without the v2.3.0 contract); it covers the verified-access case.\n const accessLevel: AccessLevel = apiResponse.access?.accessLevel ?? 'standard';\n\n const result: EnhancedVerificationResult = {\n // Round-18 G4: backend allowed access. Identity is verified (we resolved\n // the caller to an agent) and policy passed all gates. Read idVerified\n // from verificationContext for symmetry with the deny branch; default true\n // on success path since `access.allowed === true` implies identity was\n // resolvable (anonymous-allow paths flow through createGuidanceResponse).\n identityVerified:\n (apiResponse.verificationContext as { idVerified?: boolean } | undefined)?.idVerified !==\n false,\n policyAllowed: true,\n accessLevel,\n agent,\n developer,\n organization,\n appliedPolicy: apiResponse.access?.appliedPolicy,\n verificationContext,\n requiresStepUp: apiResponse.access?.requiresStepUp,\n requiresApproval: apiResponse.access?.requiresApproval,\n verifiedAt: new Date(),\n cacheTtl: mergedConfig.cacheTtl,\n // Handshake Protocol v10 enhanced fields (present when backend returns them)\n sessionId: (apiResponse as Record<string, unknown>).sessionId as string | undefined,\n // v2.3.10 (defect #34, round-4): anonymous responses surface correlationId\n // (no session row exists for unverified callers).\n correlationId: (apiResponse as Record<string, unknown>).correlationId as string | undefined,\n runtimeChallenge: (apiResponse as Record<string, unknown>).runtimeChallenge as\n | RuntimeChallengeResult\n | undefined,\n tokenGuidance: (apiResponse as Record<string, unknown>).tokenGuidance as\n | TokenGuidance\n | undefined,\n recommendation: (apiResponse as Record<string, unknown>)\n .recommendation as EnhancedVerificationResult['recommendation'],\n recommendationReasons: (apiResponse as Record<string, unknown>).recommendationReasons as\n | string[]\n | undefined,\n warningHeader: (apiResponse as Record<string, unknown>).warningHeader as\n | { name: string; value: string }\n | undefined,\n };\n\n // Enforce AstraSync recommendation\n if (result.recommendation === 'deny') {\n // Round-18 G4: recommendation-driven deny lands on the success-path\n // construction (identity was resolved). Flip policy only — identity stays\n // verified — so adapters return 403 (re-auth won't help; the policy\n // decision is the blocker).\n result.policyAllowed = false;\n result.accessLevel = 'none';\n result.denialReasons = result.recommendationReasons || [\n 'Access denied by AstraSync recommendation',\n ];\n if (result.runtimeChallenge) {\n result.guidance = {\n message: `Verification failed: ${result.runtimeChallenge.reason || 'runtime challenge failed'}`,\n registrationUrl: `${mergedConfig.apiBaseUrl?.replace('/api', '')}/register`,\n documentationUrl: `${mergedConfig.apiBaseUrl?.replace('/api', '')}/docs/runtime-challenge`,\n };\n }\n } else if (result.recommendation === 'step_up_required') {\n result.requiresStepUp = true;\n if (ACCESS_LEVEL_HIERARCHY[result.accessLevel] > ACCESS_LEVEL_HIERARCHY['read-only']) {\n result.accessLevel = 'read-only';\n }\n result.denialReasons = result.recommendationReasons || ['Step-up verification required'];\n }\n\n // Cache the result (skip caching denials — agent may fix challenge endpoint\n // and retry). Round-18.5 F4: cacheResult applies split default (60s/300s)\n // when configuredTtl is undefined; honours the caller's value when set.\n if (mergedConfig.cacheTtl !== 0 && result.recommendation !== 'deny') {\n cacheResult(request, result, mergedConfig.cacheTtl);\n }\n\n return result;\n}\n\n/**\n * Record a counterparty's grant/deny decision for a verification session.\n * Fire-and-forget — errors are silently swallowed.\n */\n/**\n * v2.3.9 (defect #34): optional override metadata. Set when the SDK's\n * local enforcement (toolGate / methodGate / trustScore floor) rejected\n * a request the SERVER had granted. Backend emits a distinct\n * `verification.local_override` event so the activity feed surfaces the\n * divergence as a separate row.\n */\nexport interface DecisionOverride {\n overriddenBy: 'toolGate' | 'methodGate' | 'trustScore' | 'other';\n toolName?: string;\n requestedLevel?: AccessLevel;\n grantedLevel?: AccessLevel;\n}\n\nexport async function recordDecision(\n config: GatewayConfig,\n sessionId: string,\n decision: 'granted' | 'denied',\n reason?: string,\n override?: DecisionOverride\n): Promise<void> {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n headers['X-API-Key'] = config.apiKey;\n }\n\n await fetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n decision,\n reason,\n ...(override && {\n overriddenBy: override.overriddenBy,\n toolName: override.toolName,\n requestedLevel: override.requestedLevel,\n grantedLevel: override.grantedLevel,\n }),\n }),\n }).catch(() => {\n /* fire-and-forget */\n });\n}\n\n/**\n * v2.3.10 (defect #34, round-4): record a SDK-side local override for an\n * anonymous verify-access response. Anonymous traffic has no session row, so\n * `recordDecision` (above) doesn't apply — but we still need to surface the\n * dashboard-vs-runtime divergence (e.g. server granted with audit warning\n * but local toolGate floor denied) on the activity feed.\n *\n * Backend ties the resulting `verification.local_override` event back to the\n * original `verification.unverified_audit` event via `correlationId`. The\n * endpoint is sessionless — see the docstring on the backend route for the\n * abuse-mitigation rationale (rate-limited per IP).\n *\n * Fire-and-forget — errors are silently swallowed.\n */\nexport async function recordAnonymousLocalOverride(\n config: GatewayConfig,\n correlationId: string,\n override: DecisionOverride,\n reason?: string\n): Promise<void> {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n headers['X-API-Key'] = config.apiKey;\n }\n\n await fetch(`${config.apiBaseUrl}/agents/verify-access/local-override`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n correlationId,\n reason,\n overriddenBy: override.overriddenBy,\n toolName: override.toolName,\n requestedLevel: override.requestedLevel,\n grantedLevel: override.grantedLevel,\n }),\n }).catch(() => {\n /* fire-and-forget */\n });\n}\n\n/**\n * Fetch the per-route policy for an endpoint from the AstraSync backend.\n * v2.9.7 moved policy authority into the dashboard — the SDK no longer\n * accepts `routes` from merchant-side source code, it fetches them from\n * here on init (and refreshes periodically).\n *\n * Returns `null` when the request fails for any reason — the caller decides\n * how to fall back (the middleware allows-all when no policy is loaded so\n * a misconfigured init doesn't take down the merchant's API).\n */\nexport async function fetchRoutes(\n config: GatewayConfig,\n counterpartyId: string\n): Promise<RouteAccessConfigShape[] | null> {\n if (!counterpartyId) return null;\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n headers['X-API-Key'] = config.apiKey;\n }\n try {\n const response = await fetch(\n `${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes`,\n { method: 'GET', headers }\n );\n if (!response.ok) return null;\n const body = (await response.json()) as { data?: { routes?: RouteAccessConfigShape[] } };\n return body.data?.routes ?? [];\n } catch {\n return null;\n }\n}\n\n/**\n * Minimal shape of an EndpointRoute as the SDK consumes it. Mirrors the\n * server's `EndpointRoute` type and the SDK's `RouteAccessConfig` — same\n * JSON moves between server and SDK unchanged.\n */\nexport interface RouteAccessConfigShape {\n pattern: string;\n method: string;\n minAccessLevel: 'none' | 'restricted' | 'read-only' | 'standard' | 'full' | 'internal';\n minTrustScore?: number;\n requiredPurposes?: string[];\n allowedPurposes?: string[];\n allowedJurisdictions?: string[];\n maxDuration?: number;\n maxTransactionValue?: number;\n}\n\n/**\n * Verify an agent AND automatically record the grant/deny decision.\n *\n * This is the recommended entry point for counterparties that call verify()\n * directly (e.g. MCP servers) rather than using createMiddleware().\n * It adds createSession: true, then fire-and-forgets the decision.\n */\nexport async function verifyAndRecord(\n config: GatewayConfig,\n request: VerificationRequest\n): Promise<VerificationResult> {\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\n const result = await verify(mergedConfig, { ...request, createSession: true });\n const sessionId = (result as EnhancedVerificationResult).sessionId;\n\n if (sessionId) {\n // Round-18 G4: a session is \"granted\" only if identity verified AND\n // policy allowed; either failing is a deny.\n if (result.identityVerified && result.policyAllowed) {\n recordDecision(mergedConfig, sessionId, 'granted').catch(() => {});\n } else {\n recordDecision(mergedConfig, sessionId, 'denied', result.denialReasons?.[0]).catch(() => {});\n }\n }\n\n return result;\n}\n\n/**\n * Report an unregistered agent attempt (no AstraSync credentials).\n * Called by SDK adapters when an agent is redirected to /docs/agent-access.\n * Fire-and-forget — errors are silently swallowed.\n */\nexport async function reportUnregisteredAttempt(\n config: GatewayConfig,\n data: {\n counterpartyUrl: string;\n counterpartyType?: string;\n sourceIp?: string;\n userAgent?: string;\n requestPath?: string;\n requestMethod?: string;\n }\n): Promise<void> {\n const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl!;\n\n await fetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n }).catch(() => {\n /* fire-and-forget */\n });\n}\n\n/**\n * Report a counterparty-side PDLSS pre-check failure.\n * Called by SDK adapters when the agent's requested PDLSS exceeds\n * counterparty-defined maximums BEFORE calling verify-access.\n * Fire-and-forget — errors are silently swallowed.\n */\nexport async function reportCounterpartyPreCheckFailure(\n config: GatewayConfig,\n data: {\n agentId: string;\n counterpartyUrl: string;\n counterpartyType?: string;\n failures: Array<{\n field: string;\n requested: string | number;\n limit: string | number | string[];\n message: string;\n }>;\n requestPath?: string;\n requestMethod?: string;\n }\n): Promise<void> {\n const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl!;\n\n await fetch(`${apiBaseUrl}/verification-activity/counterparty-pre-check-failure`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n }).catch(() => {\n /* fire-and-forget */\n });\n}\n\n/**\n * Quick verification — checks credentials and policy in one call.\n *\n * Round-18 G4: return shape mirrors `VerificationResult`'s split — partners\n * writing custom handlers around `quickVerify` get the same identity/policy\n * distinction as those calling `verify()` directly. Map to HTTP status the\n * same way: `!identityVerified` → 401; `identityVerified && !policyAllowed`\n * → 403.\n */\nexport async function quickVerify(\n config: GatewayConfig,\n credentials: AgentCredentials\n): Promise<{\n identityVerified: boolean;\n policyAllowed: boolean;\n accessLevel: AccessLevel;\n reason?: string;\n}> {\n const result = await verify(config, {\n credentials,\n purpose: 'verification',\n });\n\n return {\n identityVerified: result.identityVerified,\n policyAllowed: result.policyAllowed,\n accessLevel: result.accessLevel,\n reason: result.denialReasons?.[0],\n };\n}\n","/**\n * AstraSync Universal Verification Gateway - Express Middleware\n *\n * Express.js middleware for verifying AI agents on API endpoints.\n *\n * @example\n * ```typescript\n * import express from 'express';\n * import { createMiddleware } from '@astrasyncai/verification-gateway/express';\n *\n * const app = express();\n *\n * app.use(createMiddleware({\n * apiBaseUrl: 'https://astrasync.ai/api',\n * routes: [\n * { pattern: '/api/public/*', method: '*', minAccessLevel: 'none' },\n * { pattern: '/api/data/*', method: 'GET', minAccessLevel: 'read-only' },\n * { pattern: '/api/data/*', method: '*', minAccessLevel: 'standard' },\n * { pattern: '/api/admin/*', method: '*', minAccessLevel: 'internal' },\n * ],\n * }));\n * ```\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type {\n ExpressMiddlewareOptions,\n AgentCredentials,\n VerificationResult,\n EnhancedVerificationResult,\n RouteAccessConfig,\n AstraSyncCredentials,\n} from '../types';\nimport {\n verify,\n extractCredentials,\n recordDecision,\n reportCounterpartyPreCheckFailure,\n fetchRoutes,\n} from '../verify';\nimport { hasMinimumAccess } from '../access-levels';\nimport { extractHttpCredentials } from '../transport/http';\nimport { performCounterpartyPreCheck } from '../pdlss-pre-check';\n\n/**\n * Extend Express Request with verification result\n */\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Express {\n interface Request {\n agentVerification?: VerificationResult;\n }\n }\n}\n\n/**\n * Default credential extractor\n */\nfunction defaultExtractCredentials(req: Request): AgentCredentials {\n return extractCredentials(\n req.headers as Record<string, string | string[] | undefined>,\n req.query as Record<string, string | undefined>\n );\n}\n\n/**\n * Extract extended AstraSync credentials (X-Astra-* headers) from Express request.\n * Returns null if no AstraSync headers are present.\n */\nexport function extractAstraSyncCredentials(req: Request): AstraSyncCredentials | null {\n return extractHttpCredentials(req.headers as Record<string, string | string[] | undefined>);\n}\n\n/**\n * Default purpose extractor.\n *\n * Priority:\n * 1. Agent's declared PDLSS purpose from X-Astra-Purpose header (e.g. \"read_data:search\")\n * 2. Explicit x-purpose header\n * 3. Query parameter ?purpose=\n * 4. HTTP method → PDLSS category fallback\n */\nfunction defaultExtractPurpose(req: Request): string | undefined {\n // 1. Check agent's declared PDLSS purpose (X-Astra-Purpose header)\n const astraPurpose = req.headers['x-astra-purpose'];\n if (astraPurpose) {\n const value = Array.isArray(astraPurpose) ? astraPurpose[0] : astraPurpose;\n // Extract category from \"category:action\" format — the verify API expects the category\n const category = value.split(':')[0];\n return category;\n }\n\n // 2. Try explicit purpose header\n const purposeHeader = req.headers['x-purpose'] || req.headers['X-Purpose'];\n if (purposeHeader) {\n return Array.isArray(purposeHeader) ? purposeHeader[0] : purposeHeader;\n }\n\n // 3. Try query parameter\n if (req.query.purpose && typeof req.query.purpose === 'string') {\n return req.query.purpose;\n }\n\n // 4. Infer from HTTP method using PDLSS-compatible categories\n switch (req.method) {\n case 'GET':\n return 'read_data';\n case 'POST':\n return 'write_data';\n case 'PUT':\n case 'PATCH':\n return 'write_data';\n case 'DELETE':\n return 'delete_data';\n default:\n return 'general';\n }\n}\n\n/**\n * Match a route pattern against a path\n */\nfunction matchRoute(pattern: string, path: string): boolean {\n // Convert pattern to regex\n const regexPattern = pattern.replace(/\\*/g, '.*').replace(/\\//g, '\\\\/');\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(path);\n}\n\n/**\n * Find the route configuration for a request\n */\nfunction findRouteConfig(\n routes: RouteAccessConfig[],\n path: string,\n method: string\n): RouteAccessConfig | undefined {\n return routes.find((route) => {\n const methodMatches =\n route.method === '*' || route.method.toUpperCase() === method.toUpperCase();\n const pathMatches = matchRoute(route.pattern, path);\n return methodMatches && pathMatches;\n });\n}\n\n/**\n * Default denied handler\n *\n * Round-10 (#47, O5): the response body now carries the full `failures[]`\n * array and the `correlationId` so partners can render per-dimension UX\n * and tie a denial back to a server log line. Previously the merchant only\n * got the first denialReason — meaningful detail was thrown away before\n * the response left the SDK. Also stamps `X-Astra-Gateway-Mode: enforced`\n * so partners can tell a gate-evaluated denial apart from a gate-skipped\n * pass-through (#49/O10 — the `unenforced` complement).\n */\nfunction defaultOnDenied(result: VerificationResult, _req: Request, res: Response): void {\n // Round-18 G4: identity-verification failures → 401 (re-authenticate);\n // identity-verified-but-policy-denied → 403 (re-auth won't help; update\n // PDLSS scope or escalate to step-up). Maps to the two distinct recovery\n // actions that HTTP middleware acts on without parsing bodies. The\n // impossible state `!identityVerified && policyAllowed` falls into the\n // `!identityVerified` branch — identity is the more-fundamental missing\n // precondition.\n const statusCode = !result.identityVerified ? 401 : 403;\n\n res.setHeader('X-Astra-Gateway-Mode', 'enforced');\n\n res.status(statusCode).json({\n success: false,\n error: {\n code: !result.identityVerified ? 'UNAUTHORIZED' : 'INSUFFICIENT_ACCESS',\n message: result.denialReasons?.[0] || 'Access denied',\n accessLevel: result.accessLevel,\n guidance: result.guidance,\n // Round-10: aggregated per-dimension detail + correlation handle.\n failures: result.failures,\n correlationId: result.correlationId,\n },\n });\n}\n\n/**\n * Refresh interval for the remote-fetched route policy. Default: every 5\n * minutes. Override via `routesRefreshMs` on the middleware options. Each\n * middleware instance keeps its own cache; multiple instances pointing at the\n * same endpoint will each fetch independently.\n */\nconst DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1000;\n\n/**\n * Create Express middleware for agent verification.\n *\n * v2.9.7 moved per-route policy authority out of merchant-side source code\n * into the AstraSync dashboard. `createMiddleware` no longer accepts a\n * `routes` array — it fetches the endpoint's stored policy via\n * `GET /endpoints/:counterpartyId/routes` on init and refreshes\n * periodically. Policy edits in the dashboard take effect on the next\n * refresh (or sooner if the operator manually restarts the SDK).\n *\n * `counterpartyId` is required: the SDK can't know which endpoint's policy\n * to fetch without it. Local-development workflows that don't have an\n * AstraSync endpoint registered can omit it — the middleware logs a\n * one-time warning and falls through (allows all) until a policy is\n * fetchable.\n */\nexport function createMiddleware(options: ExpressMiddlewareOptions): RequestHandler {\n const {\n extractCredentials: customExtractCredentials,\n extractPurpose: customExtractPurpose,\n skipPaths = [],\n onDenied = defaultOnDenied,\n recordDecisions,\n enableRuntimeChallenge = true,\n routesRefreshMs = DEFAULT_ROUTES_REFRESH_MS,\n ...config\n } = options;\n\n // Per-middleware-instance route cache. Populated on first fetch; refreshed\n // every `routesRefreshMs`. Until first successful fetch we hold an empty\n // array which means \"no per-route gating active\" — the middleware falls\n // through. Pre-fix the array came from merchant source, which both broke\n // the auth-boundary story (defect 24) and silently disagreed with the\n // dashboard.\n let cachedRoutes: RouteAccessConfig[] = [];\n let lastFetchAt = 0;\n let refreshing: Promise<void> | null = null;\n let warnedNoCounterparty = false;\n let warnedEmptyRoutes = false;\n\n async function refreshRoutes(): Promise<void> {\n if (!config.counterpartyId) {\n if (!warnedNoCounterparty) {\n // eslint-disable-next-line no-console\n console.warn(\n '[VerificationGateway] No counterpartyId configured — falling through (allow all). ' +\n 'Per-route policy lives in the AstraSync dashboard now; register the endpoint and ' +\n 'set counterpartyId in your middleware config to enforce policy.'\n );\n warnedNoCounterparty = true;\n }\n return;\n }\n const fetched = await fetchRoutes(config, config.counterpartyId);\n if (fetched) {\n cachedRoutes = fetched;\n lastFetchAt = Date.now();\n // v2.3.8 (defect #25): if the fetch succeeded but returned an empty\n // policy, the endpoint is registered correctly but the operator hasn't\n // configured any routes yet — every request will fall through ungated.\n // Surface this loudly once so silent pass-through can't go unnoticed.\n if (cachedRoutes.length === 0 && !warnedEmptyRoutes) {\n const dashboard = config.dashboardUrl ?? 'https://app.astrasync.ai';\n // eslint-disable-next-line no-console\n console.warn(\n `[VerificationGateway] No route policy configured for ${config.counterpartyId}. ` +\n `Gateway is in pass-through mode for ALL traffic until you add at least one route. ` +\n `Configure at ${dashboard}/dashboard/endpoints/${config.counterpartyId}/routes`\n );\n warnedEmptyRoutes = true;\n }\n }\n }\n\n // Eager first fetch so the first request after init has policy loaded.\n // Errors are swallowed (handled by fetchRoutes returning null).\n refreshing = refreshRoutes().finally(() => {\n refreshing = null;\n });\n\n return async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n // Check if path should be skipped\n const shouldSkip = skipPaths.some((pattern) => matchRoute(pattern, req.path));\n if (shouldSkip) {\n return next();\n }\n\n // Wait for in-flight init fetch (only on the very first request) so we\n // don't admit traffic with no policy loaded.\n if (refreshing) {\n await refreshing.catch(() => {});\n }\n // Time-based refresh: kick off a background refresh if the cache is\n // stale. Doesn't block the current request — readers see whatever is\n // cached at this moment; the next request will see the refreshed copy.\n if (config.counterpartyId && Date.now() - lastFetchAt > routesRefreshMs) {\n refreshing = refreshRoutes().finally(() => {\n refreshing = null;\n });\n }\n\n // Find route configuration\n const routeConfig = findRouteConfig(cachedRoutes, req.path, req.method);\n\n // If no route config, skip verification (allow through)\n if (!routeConfig) {\n if (config.setPassThroughHeader) {\n // Round-10 (#49, O10): `unenforced` replaces the previous\n // `pass-through` label. The previous name conflated \"gateway\n // didn't evaluate policy\" with \"request succeeded end-to-end\" —\n // the downstream handler may still return any status. The new\n // semantic describes the GATE state only.\n res.setHeader('X-Astra-Gateway-Mode', 'unenforced');\n res.setHeader(\n 'X-Astra-Gateway-Reason',\n cachedRoutes.length === 0 ? 'no-policy' : 'no-match'\n );\n }\n return next();\n }\n\n // Extract credentials (hoisted from below the route-none check so the\n // round-12 F9 evaluateAlwaysIfCredentialed flag can decide whether to\n // evaluate vs short-circuit).\n const credentials = customExtractCredentials\n ? customExtractCredentials(req)\n : defaultExtractCredentials(req);\n\n // Round-12 (F9): route-none short-circuit unless the caller wants\n // evaluation-without-enforcement. With evaluateAlwaysIfCredentialed\n // set to true AND credentials present, the middleware calls\n // verify-access for audit + req.agentVerification population, then\n // proceeds without gating. Default behaviour (flag off) preserves\n // pre-F9 short-circuit semantics.\n const shouldEnforce = routeConfig.minAccessLevel !== 'none';\n if (\n routeConfig.minAccessLevel === 'none' &&\n (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)\n ) {\n if (config.setPassThroughHeader) {\n res.setHeader('X-Astra-Gateway-Mode', 'unenforced');\n res.setHeader('X-Astra-Gateway-Reason', 'route-none');\n }\n return next();\n }\n\n // v2.3.0: anonymous traffic no longer short-circuits client-side.\n // The server applies the endpoint's `unverifiedAgentPolicy` (deny /\n // allow_partial / allow_full) and emits the verification event +\n // blockchain record per the canonical flow. SDK forwards verbatim.\n\n // Extract purpose\n const purpose = customExtractPurpose ? customExtractPurpose(req) : defaultExtractPurpose(req);\n\n // Extract full AstraSync credentials (includes PDLSS from X-Astra-* headers)\n const astraCreds = extractAstraSyncCredentials(req);\n\n // Auto-detect counterparty URL from the request if not explicitly configured.\n // Since the SDK is installed at this endpoint, we always know the origin.\n const counterpartyUrl = config.counterpartyUrl || `${req.protocol}://${req.get('host')}`;\n\n // Step 2: Counterparty-side PDLSS pre-check — compare agent's requested PDLSS\n // against counterparty-defined maximums on the route config.\n // Rejects immediately if outside limits, BEFORE calling verify-access.\n const preCheckFailures = performCounterpartyPreCheck(routeConfig, astraCreds, purpose);\n if (preCheckFailures.length > 0) {\n // Round-18 G4: counterparty pre-check failure — request rejected\n // before reaching verify-access. Neither identity nor policy was\n // remotely verified; both axes truthfully false.\n const result: VerificationResult = {\n identityVerified: false,\n policyAllowed: false,\n accessLevel: 'none',\n denialReasons: preCheckFailures.map((f) => f.message),\n guidance: {\n message: 'Request exceeds counterparty-defined PDLSS limits.',\n registrationUrl: `${config.apiBaseUrl?.replace('/api', '')}/register`,\n documentationUrl: `${config.apiBaseUrl?.replace('/api', '')}/docs/pdlss`,\n },\n verifiedAt: new Date(),\n };\n\n req.agentVerification = result;\n\n // Fire-and-forget: notify AstraSync of the pre-check failure\n reportCounterpartyPreCheckFailure(config, {\n agentId: astraCreds?.agentId || credentials.astraId || 'unknown',\n counterpartyUrl,\n counterpartyType: config.counterpartyType || 'api',\n failures: preCheckFailures,\n requestPath: req.path,\n requestMethod: req.method,\n }).catch(() => {});\n\n onDenied(result, req, res);\n return;\n }\n\n // Step 3: Call AstraSync verify-access with runtime challenge enabled\n const shouldRecordDecisions = recordDecisions !== false;\n const forwardedFor = req.headers['x-forwarded-for'];\n const forwardedForStr = Array.isArray(forwardedFor) ? forwardedFor.join(', ') : forwardedFor;\n // X-Forwarded-For's first entry is the original client. Fall back to req.ip\n // (which Express already resolves via trust proxy settings when configured).\n const originalClientIp = forwardedForStr ? forwardedForStr.split(',')[0].trim() : req.ip;\n const agentCardUrl =\n typeof req.headers['x-astrasync-agent-card'] === 'string'\n ? (req.headers['x-astrasync-agent-card'] as string)\n : undefined;\n\n const result = await verify(config, {\n credentials,\n purpose,\n action: req.method.toLowerCase(),\n resource: req.path,\n createSession: shouldRecordDecisions,\n counterpartyUrl,\n counterpartyType: config.counterpartyType || 'api',\n enableRuntimeChallenge,\n durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration,\n callerMetadata: {\n sourceIp: originalClientIp,\n userAgent: req.headers['user-agent'] as string | undefined,\n referer: req.headers.referer as string | undefined,\n host: req.headers.host as string | undefined,\n forwardedFor: forwardedForStr,\n agentCardUrl,\n },\n });\n\n // Attach result to request\n req.agentVerification = result;\n const sessionId = (result as EnhancedVerificationResult).sessionId;\n\n // v2.3.9 (defect #30): denied verifications short-circuit BEFORE the\n // gate-level comparison. Pre-rename, denials returned\n // `accessLevel: 'guidance'` and routes gated at `'guidance'` passed\n // `hasMinimumAccess('guidance', 'guidance') === true` — letting\n // unverified anonymous traffic through to the merchant handler. The\n // verify.ts denial branches now return `'none'` (so the gate check\n // alone would correctly deny), but trusting access-level math for a\n // denial is a category error: failing either identity OR policy already\n // means \"deny.\" We check that first.\n // Round-18 G4: short-circuit on either axis failing — identity-fail\n // (no resolved caller) or policy-fail (PDLSS or recommendation deny).\n if (!result.identityVerified || !result.policyAllowed) {\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'denied', result.denialReasons?.[0]).catch(() => {});\n }\n onDenied(result, req, res);\n return;\n }\n\n // Round-12 (F9): evaluation-without-enforcement. When the route is\n // 'none' but we ran verify-access for audit, skip the gates and call\n // next() — the result is on req.agentVerification for the handler\n // to render tier-aware responses (e.g. anonymous vs verified\n // catalog view on the same path).\n if (!shouldEnforce) {\n if (config.setPassThroughHeader) {\n res.setHeader('X-Astra-Gateway-Mode', 'enforced');\n res.setHeader('X-Astra-Gateway-Reason', 'evaluated-not-enforced');\n }\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'granted').catch(() => {});\n }\n return next();\n }\n\n // Check if access level is sufficient (verified caller path only —\n // denials handled above)\n if (!hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {\n // Round-12 (F12): synthesise the structured failure entry so the\n // partner-facing response carries the same shape as every other\n // denial dimension. Guidance positions step-up only — increasing\n // trust score or lowering the route floor both read as gaming the\n // gate. Step-up flow ships separately this month.\n const insufficientFailure = {\n dimension: 'access_level.insufficient',\n message: `Endpoint requires accessLevel '${routeConfig.minAccessLevel}'; agent has '${result.accessLevel}'.`,\n guidance:\n \"Request elevated access via step-up verification (coming soon — ships this month). Step-up lets the agent owner approve a one-time elevation for this specific counterparty + purpose without changing the agent's baseline trust score.\",\n };\n result.failures = [...(result.failures ?? []), insufficientFailure];\n result.denialReasons = [...(result.denialReasons ?? []), insufficientFailure.message];\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'denied', insufficientFailure.message).catch(() => {});\n }\n onDenied(result, req, res);\n return;\n }\n\n // Check trust score requirement if specified\n if (routeConfig.minTrustScore && result.agent) {\n if (result.agent.trustScore < routeConfig.minTrustScore) {\n // Round-12 (F12): structured failure entry + step-up framing.\n const trustFailure = {\n dimension: 'access_level.insufficient',\n message: `Trust score ${result.agent.trustScore} is below required ${routeConfig.minTrustScore} for this route.`,\n guidance:\n \"Request elevated access via step-up verification (coming soon — ships this month). Step-up lets the agent owner approve a one-time elevation for this specific counterparty + purpose without changing the agent's baseline trust score.\",\n };\n result.failures = [...(result.failures ?? []), trustFailure];\n result.denialReasons = [trustFailure.message];\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'denied', trustFailure.message).catch(() => {});\n }\n onDenied(result, req, res);\n return;\n }\n }\n\n // All checks passed — record grant decision\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'granted').catch(() => {});\n }\n // v2.3.8 (defect #26): if the endpoint's `unverifiedAgentPolicy` is\n // `'audit'` (allow + soft-launch warning), the server returns the\n // header to relay. Lift it onto the merchant's response BEFORE\n // calling next() so downstream handlers and the eventual response\n // back to the agent both carry it.\n const enhancedResult = result as EnhancedVerificationResult;\n if (enhancedResult.warningHeader) {\n res.setHeader(enhancedResult.warningHeader.name, enhancedResult.warningHeader.value);\n }\n next();\n } catch (error) {\n // Log error and continue (fail open by default)\n console.error('[VerificationGateway] Middleware error:', error);\n next();\n }\n };\n}\n\n// `requireAccess` and `verifyOnly` were removed in v2.9.7. Both injected a\n// local `routes` array into the merchant's source code, which is the exact\n// dual-config attack vector defect 24 closed. Per-route policy now lives in\n// the AstraSync dashboard (gated by team.role admin auth + audit + alerts).\n// To enforce a minimum tier, set the route's `minAccessLevel` in the\n// dashboard. For \"verify but don't block,\" set every route to `none` there.\n","/**\n * HTTP Transport Adapter\n *\n * Maps AstraSync credentials to/from HTTP headers (X-Astra-* convention).\n */\n\nimport type { AstraSyncCredentials } from '../types';\n\nconst HEADER_PREFIX = 'X-Astra-';\n\n/**\n * Inject AstraSync credentials into HTTP headers.\n */\nexport function setHttpHeaders(\n headers: Record<string, string>,\n credentials: AstraSyncCredentials,\n): Record<string, string> {\n const result = { ...headers };\n\n result[`${HEADER_PREFIX}ID`] = credentials.agentId;\n\n if (credentials.verifyUrl) {\n result[`${HEADER_PREFIX}Verify`] = credentials.verifyUrl;\n }\n\n if (credentials.challengeUrl) {\n result[`${HEADER_PREFIX}Challenge`] = credentials.challengeUrl;\n }\n\n if (credentials.pdlss?.purpose) {\n const purposeValue = credentials.pdlss.purpose.action\n ? `${credentials.pdlss.purpose.category}:${credentials.pdlss.purpose.action}`\n : credentials.pdlss.purpose.category;\n result[`${HEADER_PREFIX}Purpose`] = purposeValue;\n }\n\n if (credentials.pdlss?.duration?.maxSessionDuration) {\n result[`${HEADER_PREFIX}Duration`] = String(credentials.pdlss.duration.maxSessionDuration);\n }\n\n if (credentials.pdlss?.scope?.jurisdiction) {\n result[`${HEADER_PREFIX}Scope`] = credentials.pdlss.scope.jurisdiction;\n }\n\n return result;\n}\n\n/**\n * Extract AstraSync credentials from HTTP headers.\n */\nexport function extractHttpCredentials(\n headers: Record<string, string | string[] | undefined>,\n): AstraSyncCredentials | null {\n const getValue = (key: string): string | undefined => {\n const v = headers[key] ?? headers[key.toLowerCase()];\n return Array.isArray(v) ? v[0] : v;\n };\n\n const agentId = getValue(`${HEADER_PREFIX}ID`) ?? getValue('x-astra-id');\n if (!agentId) return null;\n\n const credentials: AstraSyncCredentials = { agentId };\n\n const verifyUrl = getValue(`${HEADER_PREFIX}Verify`) ?? getValue('x-astra-verify');\n if (verifyUrl) credentials.verifyUrl = verifyUrl;\n\n const challengeUrl = getValue(`${HEADER_PREFIX}Challenge`) ?? getValue('x-astra-challenge');\n if (challengeUrl) credentials.challengeUrl = challengeUrl;\n\n const purpose = getValue(`${HEADER_PREFIX}Purpose`) ?? getValue('x-astra-purpose');\n if (purpose) {\n const [category, action] = purpose.split(':');\n credentials.pdlss = {\n ...credentials.pdlss,\n purpose: { category, action },\n };\n }\n\n const duration = getValue(`${HEADER_PREFIX}Duration`) ?? getValue('x-astra-duration');\n if (duration) {\n credentials.pdlss = {\n ...credentials.pdlss,\n duration: { maxSessionDuration: parseInt(duration, 10) },\n };\n }\n\n const scope = getValue(`${HEADER_PREFIX}Scope`) ?? getValue('x-astra-scope');\n if (scope) {\n credentials.pdlss = {\n ...credentials.pdlss,\n scope: { jurisdiction: scope },\n };\n }\n\n return credentials;\n}\n","/**\n * Counterparty-side PDLSS pre-check.\n *\n * Compares the agent's requested PDLSS dimensions (from X-Astra-* headers)\n * against the counterparty-defined maximums on the route config.\n * Returns an array of failures — empty means all checks passed.\n *\n * This runs BEFORE calling verify-access on AstraSync. If it fails,\n * the request is rejected immediately without calling the platform.\n */\n\nimport type { RouteAccessConfig, AstraSyncCredentials, CounterpartyPreCheckFailure } from './types';\n\nexport function performCounterpartyPreCheck(\n routeConfig: RouteAccessConfig,\n astraCreds: AstraSyncCredentials | null,\n purpose: string | undefined\n): CounterpartyPreCheckFailure[] {\n const failures: CounterpartyPreCheckFailure[] = [];\n\n // Check purpose against allowedPurposes whitelist (round-18.5 F3: request-\n // driven fail-closed — if the request carries a purpose, the route must\n // enumerate allowedPurposes for it to be valid).\n if (purpose) {\n if (!routeConfig.allowedPurposes || routeConfig.allowedPurposes.length === 0) {\n failures.push({\n field: 'purpose',\n requested: purpose,\n limit: [],\n message: `Purpose \"${purpose}\" not allowed: route declares no allowedPurposes. The endpoint owner must enumerate allowedPurposes on the route config to authorise specific purposes.`,\n });\n } else if (!routeConfig.allowedPurposes.includes(purpose)) {\n failures.push({\n field: 'purpose',\n requested: purpose,\n limit: routeConfig.allowedPurposes,\n message: `Purpose \"${purpose}\" is not in the allowed list: [${routeConfig.allowedPurposes.join(', ')}]`,\n });\n }\n }\n\n // Check purpose against requiredPurposes (legacy field — agent must declare one of these)\n if (routeConfig.requiredPurposes && routeConfig.requiredPurposes.length > 0 && purpose) {\n if (!routeConfig.requiredPurposes.includes(purpose)) {\n failures.push({\n field: 'purpose',\n requested: purpose,\n limit: routeConfig.requiredPurposes,\n message: `Purpose \"${purpose}\" is not in the required list: [${routeConfig.requiredPurposes.join(', ')}]`,\n });\n }\n }\n\n // Check duration against maxDuration — range-check (unchanged; undefined =\n // no upper bound is conventional for opt-in range fields, not a request-\n // driven allow-list).\n if (routeConfig.maxDuration && astraCreds?.pdlss?.duration?.maxSessionDuration) {\n const requested = astraCreds.pdlss.duration.maxSessionDuration;\n if (requested > routeConfig.maxDuration) {\n failures.push({\n field: 'duration',\n requested,\n limit: routeConfig.maxDuration,\n message: `Requested duration ${requested}s exceeds maximum ${routeConfig.maxDuration}s`,\n });\n }\n }\n\n // Check jurisdiction against allowedJurisdictions (round-18.5 F3:\n // request-driven fail-closed — if the request carries a jurisdiction, the\n // route must enumerate allowedJurisdictions).\n if (astraCreds?.pdlss?.scope?.jurisdiction) {\n const requested = astraCreds.pdlss.scope.jurisdiction;\n if (!routeConfig.allowedJurisdictions || routeConfig.allowedJurisdictions.length === 0) {\n failures.push({\n field: 'jurisdiction',\n requested,\n limit: [],\n message: `Jurisdiction \"${requested}\" not allowed: route declares no allowedJurisdictions. The endpoint owner must enumerate allowedJurisdictions on the route config to authorise specific jurisdictions.`,\n });\n } else if (!routeConfig.allowedJurisdictions.includes(requested)) {\n failures.push({\n field: 'jurisdiction',\n requested,\n limit: routeConfig.allowedJurisdictions,\n message: `Jurisdiction \"${requested}\" is not in the allowed list: [${routeConfig.allowedJurisdictions.join(', ')}]`,\n });\n }\n }\n\n return failures;\n}\n","/**\n * AstraSync Universal Verification Gateway - Next.js Middleware\n *\n * Next.js middleware for verifying AI agents on web applications.\n * Supports Commerce Shield overlay for unverified agents.\n *\n * @example\n * ```typescript\n * // middleware.ts\n * import { createMiddleware } from '@astrasyncai/verification-gateway/nextjs';\n *\n * export const middleware = createMiddleware({\n * apiBaseUrl: 'https://api.astrasync.ai',\n * showCommerceShield: true,\n * routes: [\n * { pattern: '/api/public/*', method: '*', minAccessLevel: 'none' },\n * { pattern: '/api/*', method: '*', minAccessLevel: 'standard' },\n * { pattern: '/dashboard/*', method: '*', minAccessLevel: 'read-only' },\n * ],\n * });\n *\n * export const config = {\n * matcher: ['/api/:path*', '/dashboard/:path*'],\n * };\n * ```\n */\n\nimport type { NextRequest } from 'next/server';\nimport type {\n NextJsMiddlewareOptions,\n AgentCredentials,\n VerificationResult,\n RouteAccessConfig,\n AstraSyncCredentials,\n} from '../types';\nimport { verify, reportCounterpartyPreCheckFailure, fetchRoutes } from '../verify';\nimport { hasMinimumAccess } from '../access-levels';\nimport { extractHttpCredentials } from '../transport/http';\nimport { performCounterpartyPreCheck } from '../pdlss-pre-check';\n\n/**\n * Extract credentials from Next.js request\n */\nfunction extractCredentialsFromNextRequest(request: NextRequest): AgentCredentials {\n const credentials: AgentCredentials = {};\n\n // Check for ASTRA-ID in headers\n const astraId = request.headers.get('x-astra-id') || request.headers.get('X-Astra-Id');\n if (astraId) {\n credentials.astraId = astraId;\n }\n\n // Check for API key\n const apiKey = request.headers.get('x-api-key') || request.headers.get('X-Api-Key');\n if (apiKey) {\n credentials.apiKey = apiKey;\n }\n\n // Check Authorization header\n const authHeader = request.headers.get('authorization');\n if (authHeader) {\n credentials.authorizationHeader = authHeader;\n if (authHeader.startsWith('Bearer ')) {\n credentials.jwt = authHeader.slice(7);\n }\n }\n\n // Check query parameters\n const url = new URL(request.url);\n const astraIdParam = url.searchParams.get('astraId');\n const apiKeyParam = url.searchParams.get('apiKey');\n\n if (astraIdParam && !credentials.astraId) {\n credentials.astraId = astraIdParam;\n }\n if (apiKeyParam && !credentials.apiKey) {\n credentials.apiKey = apiKeyParam;\n }\n\n return credentials;\n}\n\n/**\n * Match a route pattern against a path\n */\nfunction matchRoute(pattern: string, path: string): boolean {\n const regexPattern = pattern.replace(/\\*/g, '.*').replace(/\\//g, '\\\\/');\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(path);\n}\n\n/**\n * Find the route configuration for a request\n */\nfunction findRouteConfig(\n routes: RouteAccessConfig[],\n path: string,\n method: string\n): RouteAccessConfig | undefined {\n return routes.find((route) => {\n const methodMatches =\n route.method === '*' || route.method.toUpperCase() === method.toUpperCase();\n const pathMatches = matchRoute(route.pattern, path);\n return methodMatches && pathMatches;\n });\n}\n\n/**\n * Extract AstraSyncCredentials from Next.js request headers.\n * Returns null if no AstraSync headers are present.\n */\nfunction extractAstraSyncCredentialsFromNextRequest(\n request: NextRequest\n): AstraSyncCredentials | null {\n const headers: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n headers[key] = value;\n });\n return extractHttpCredentials(headers);\n}\n\n/**\n * Extract purpose from request.\n *\n * Priority:\n * 1. Agent's declared PDLSS purpose from X-Astra-Purpose header (e.g. \"read_data:search\")\n * 2. Explicit x-purpose header\n * 3. HTTP method → PDLSS category fallback\n */\nfunction extractPurpose(request: NextRequest): string {\n // 1. Check agent's declared PDLSS purpose (X-Astra-Purpose header)\n const astraPurpose = request.headers.get('x-astra-purpose');\n if (astraPurpose) {\n // Extract category from \"category:action\" format\n return astraPurpose.split(':')[0];\n }\n\n // 2. Try explicit purpose header\n const purposeHeader = request.headers.get('x-purpose');\n if (purposeHeader) {\n return purposeHeader;\n }\n\n // 3. Infer from HTTP method using PDLSS-compatible categories\n switch (request.method.toUpperCase()) {\n case 'GET':\n return 'read_data';\n case 'POST':\n return 'write_data';\n case 'PUT':\n case 'PATCH':\n return 'write_data';\n case 'DELETE':\n return 'delete_data';\n default:\n return 'general';\n }\n}\n\n/**\n * Generate Commerce Shield HTML response\n */\nfunction generateCommerceShieldHtml(\n result: VerificationResult,\n options: NextJsMiddlewareOptions\n): string {\n const title = options.commerceShield?.title || 'AstraSync Agent Verification';\n const message =\n options.commerceShield?.message ||\n result.guidance?.message ||\n \"This site verifies AI agents before granting access. We noticed you're visiting without AstraSync credentials.\";\n const registrationUrl = result.guidance?.registrationUrl || 'https://astrasync.ai/register';\n const docsUrl = result.guidance?.documentationUrl || 'https://astrasync.ai/docs/agent-access';\n const allowGuest = options.commerceShield?.allowGuestAccess ?? true;\n\n return `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${title}</title>\n <style>\n * {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n }\n .shield-container {\n background: rgba(255, 255, 255, 0.95);\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);\n max-width: 480px;\n width: 100%;\n padding: 40px;\n text-align: center;\n }\n .shield-icon {\n font-size: 48px;\n margin-bottom: 20px;\n }\n .shield-title {\n font-size: 24px;\n font-weight: 700;\n color: #1a1a2e;\n margin-bottom: 16px;\n }\n .shield-message {\n color: #4a5568;\n line-height: 1.6;\n margin-bottom: 24px;\n }\n .shield-steps {\n text-align: left;\n background: #f7fafc;\n border-radius: 8px;\n padding: 20px;\n margin-bottom: 24px;\n }\n .shield-steps h3 {\n font-size: 14px;\n font-weight: 600;\n color: #2d3748;\n margin-bottom: 12px;\n }\n .shield-steps ol {\n padding-left: 20px;\n color: #4a5568;\n }\n .shield-steps li {\n margin-bottom: 8px;\n }\n .shield-buttons {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .btn {\n display: inline-block;\n padding: 14px 24px;\n border-radius: 8px;\n font-weight: 600;\n text-decoration: none;\n transition: all 0.2s;\n cursor: pointer;\n border: none;\n font-size: 16px;\n }\n .btn-primary {\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n color: white;\n }\n .btn-primary:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);\n }\n .btn-secondary {\n background: #e2e8f0;\n color: #4a5568;\n }\n .btn-secondary:hover {\n background: #cbd5e0;\n }\n .shield-footer {\n margin-top: 24px;\n font-size: 14px;\n color: #718096;\n }\n .shield-footer a {\n color: #6366f1;\n text-decoration: none;\n }\n .shield-footer a:hover {\n text-decoration: underline;\n }\n </style>\n</head>\n<body>\n <div class=\"shield-container\">\n <div class=\"shield-icon\">🛡️</div>\n <h1 class=\"shield-title\">${title}</h1>\n <p class=\"shield-message\">${message}</p>\n\n <div class=\"shield-steps\">\n <h3>To get verified access:</h3>\n <ol>\n <li>Register at <a href=\"${registrationUrl}\">astrasync.ai/register</a></li>\n <li>Create and register your agent</li>\n <li>Add your ASTRA-ID to request headers</li>\n <li>Refresh this page</li>\n </ol>\n </div>\n\n <div class=\"shield-buttons\">\n <a href=\"${registrationUrl}\" class=\"btn btn-primary\">Register Now</a>\n ${allowGuest ? '<button onclick=\"window.location.reload()\" class=\"btn btn-secondary\">Continue as Guest (Limited)</button>' : ''}\n </div>\n\n <p class=\"shield-footer\">\n Learn more: <a href=\"${docsUrl}\">Agent Access Documentation</a>\n </p>\n </div>\n</body>\n</html>\n `.trim();\n}\n\nconst DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1000;\n\n/**\n * Create Next.js middleware for agent verification.\n *\n * v2.9.7 moved per-route policy out of merchant-side source code into the\n * AstraSync dashboard. The middleware fetches its routes from the backend\n * via `GET /endpoints/:counterpartyId/routes` on init and refreshes\n * periodically — see `ExpressMiddlewareOptions` for the rationale (defect\n * 24, dual-config silent-conflict).\n */\nexport function createMiddleware(options: NextJsMiddlewareOptions) {\n const {\n skipPaths = [],\n showCommerceShield = true,\n enableRuntimeChallenge = true,\n routesRefreshMs = DEFAULT_ROUTES_REFRESH_MS,\n ...config\n } = options;\n\n let cachedRoutes: RouteAccessConfig[] = [];\n let lastFetchAt = 0;\n let refreshing: Promise<void> | null = null;\n let warnedNoCounterparty = false;\n\n async function refreshRoutes(): Promise<void> {\n if (!config.counterpartyId) {\n if (!warnedNoCounterparty) {\n // eslint-disable-next-line no-console\n console.warn(\n '[VerificationGateway/Next.js] No counterpartyId configured — falling through (allow all). ' +\n 'Per-route policy lives in the AstraSync dashboard now; register the endpoint and ' +\n 'set counterpartyId in your middleware config to enforce policy.'\n );\n warnedNoCounterparty = true;\n }\n return;\n }\n const fetched = await fetchRoutes(config, config.counterpartyId);\n if (fetched) {\n cachedRoutes = fetched;\n lastFetchAt = Date.now();\n }\n }\n\n refreshing = refreshRoutes().finally(() => {\n refreshing = null;\n });\n\n return async function middleware(request: NextRequest) {\n // Dynamic import NextResponse to avoid build issues\n const { NextResponse } = await import('next/server');\n\n const pathname = request.nextUrl.pathname;\n\n // Check if path should be skipped\n const shouldSkip = skipPaths.some((pattern) => matchRoute(pattern, pathname));\n if (shouldSkip) {\n return NextResponse.next();\n }\n\n if (refreshing) {\n await refreshing.catch(() => {});\n }\n if (config.counterpartyId && Date.now() - lastFetchAt > routesRefreshMs) {\n refreshing = refreshRoutes().finally(() => {\n refreshing = null;\n });\n }\n\n // Find route configuration (from remote-fetched cache)\n const routeConfig = findRouteConfig(cachedRoutes, pathname, request.method);\n\n // If no route config, allow through\n if (!routeConfig) {\n return NextResponse.next();\n }\n\n // If route requires 'none' access, allow through\n if (routeConfig.minAccessLevel === 'none') {\n return NextResponse.next();\n }\n\n // Extract credentials\n const credentials = extractCredentialsFromNextRequest(request);\n\n // v2.3.0: anonymous traffic no longer short-circuits client-side.\n // The server applies the endpoint's `unverifiedAgentPolicy` (deny /\n // allow_partial / allow_full) and emits the verification event +\n // blockchain record per the canonical flow. SDK forwards verbatim.\n\n // Auto-detect counterparty URL from the request if not explicitly configured.\n // Since the SDK is installed at this endpoint, we always know the origin.\n const counterpartyUrl = config.counterpartyUrl || request.nextUrl.origin;\n\n // Extract purpose and full AstraSync credentials (includes PDLSS from X-Astra-* headers)\n const purpose = extractPurpose(request);\n const astraCreds = extractAstraSyncCredentialsFromNextRequest(request);\n\n // Step 2: Counterparty-side PDLSS pre-check — compare agent's requested PDLSS\n // against counterparty-defined maximums on the route config.\n // Rejects immediately if outside limits, BEFORE calling verify-access.\n const preCheckFailures = performCounterpartyPreCheck(routeConfig, astraCreds, purpose);\n if (preCheckFailures.length > 0) {\n // Round-18 G4: counterparty pre-check failure — see express.ts for the\n // rationale. Neither axis verified remotely → both false.\n const preCheckResult: VerificationResult = {\n identityVerified: false,\n policyAllowed: false,\n accessLevel: 'none',\n denialReasons: preCheckFailures.map((f) => f.message),\n guidance: {\n message: 'Request exceeds counterparty-defined PDLSS limits.',\n registrationUrl: `${config.apiBaseUrl?.replace('/api', '')}/register`,\n documentationUrl: `${config.apiBaseUrl?.replace('/api', '')}/docs/pdlss`,\n },\n verifiedAt: new Date(),\n };\n\n // Fire-and-forget: notify AstraSync of the pre-check failure\n reportCounterpartyPreCheckFailure(config, {\n agentId: astraCreds?.agentId || credentials.astraId || 'unknown',\n counterpartyUrl,\n counterpartyType: config.counterpartyType || 'website',\n failures: preCheckFailures,\n requestPath: pathname,\n requestMethod: request.method,\n }).catch(() => {});\n\n // For API routes, return JSON\n if (pathname.startsWith('/api/')) {\n return NextResponse.json(\n {\n success: false,\n error: {\n code: 'PDLSS_PRE_CHECK_FAILED',\n message: preCheckResult.denialReasons?.[0] || 'PDLSS pre-check failed',\n guidance: preCheckResult.guidance,\n },\n },\n { status: 403 }\n );\n }\n\n // For web pages, show Commerce Shield\n if (showCommerceShield) {\n return new NextResponse(generateCommerceShieldHtml(preCheckResult, options), {\n status: 200,\n headers: {\n 'Content-Type': 'text/html',\n 'X-AstraSync-Verification': 'commerce-shield',\n },\n });\n }\n\n return NextResponse.redirect(new URL('/unauthorized', request.url));\n }\n\n // Step 3: Call AstraSync verify-access with runtime challenge enabled\n const forwardedFor = request.headers.get('x-forwarded-for') || undefined;\n const originalClientIp = forwardedFor?.split(',')[0]?.trim();\n const result = await verify(config, {\n credentials,\n purpose,\n action: request.method.toLowerCase(),\n resource: pathname,\n counterpartyUrl,\n counterpartyType: config.counterpartyType || 'website',\n enableRuntimeChallenge,\n durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration,\n callerMetadata: {\n sourceIp: originalClientIp,\n userAgent: request.headers.get('user-agent') || undefined,\n referer: request.headers.get('referer') || undefined,\n host: request.headers.get('host') || undefined,\n forwardedFor,\n agentCardUrl: request.headers.get('x-astrasync-agent-card') || undefined,\n },\n });\n\n // v2.3.9 (defect #30): denied verifications short-circuit BEFORE the\n // gate-level comparison. The OR-prefix shape here keeps the\n // single-expression branch this adapter uses, but ensures any axis of\n // failure triggers the denial path even if the access level math would\n // otherwise let it through (the historical bug). See express.ts for the\n // full rationale.\n // Round-18 G4: short-circuit on either axis failing (identity-fail or\n // policy-fail). The OR with hasMinimumAccess() preserves access-level\n // gating for over-tier requests.\n if (\n !result.identityVerified ||\n !result.policyAllowed ||\n !hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)\n ) {\n // For API routes, return JSON\n if (pathname.startsWith('/api/')) {\n return NextResponse.json(\n {\n success: false,\n error: {\n // Round-18 G4: 401 → identity missing (re-auth); 403 → identity\n // OK, policy denied (update PDLSS / step up).\n code: !result.identityVerified ? 'UNAUTHORIZED' : 'INSUFFICIENT_ACCESS',\n message: result.denialReasons?.[0] || 'Access denied',\n accessLevel: result.accessLevel,\n required: routeConfig.minAccessLevel,\n guidance: result.guidance,\n },\n },\n { status: !result.identityVerified ? 401 : 403 }\n );\n }\n\n // For web pages, show Commerce Shield\n if (showCommerceShield) {\n return new NextResponse(generateCommerceShieldHtml(result, options), {\n status: 200,\n headers: {\n 'Content-Type': 'text/html',\n 'X-AstraSync-Verification': 'commerce-shield',\n },\n });\n }\n\n // Redirect to unauthorized page\n return NextResponse.redirect(new URL('/unauthorized', request.url));\n }\n\n // All checks passed - continue with verification info in headers\n const response = NextResponse.next();\n\n // Add verification info to response headers\n // Round-18 G4: composite `verified` (identity AND policy) for legacy\n // header consumers; new headers expose each axis separately so middleware\n // chains can branch without re-running verify-access.\n response.headers.set(\n 'X-AstraSync-Verified',\n (result.identityVerified && result.policyAllowed).toString()\n );\n response.headers.set('X-AstraSync-Identity-Verified', result.identityVerified.toString());\n response.headers.set('X-AstraSync-Policy-Allowed', result.policyAllowed.toString());\n response.headers.set('X-AstraSync-Access-Level', result.accessLevel);\n\n if (result.agent) {\n response.headers.set('X-AstraSync-Agent-Id', result.agent.astraId);\n response.headers.set('X-AstraSync-Trust-Score', result.agent.trustScore.toString());\n }\n\n return response;\n };\n}\n\n/**\n * Helper to create matcher config\n */\nexport function createMatcherConfig(paths: string[]): { matcher: string[] } {\n return { matcher: paths };\n}\n","/**\n * AstraSync Universal Verification Gateway - SDK Adapter\n *\n * Direct SDK for verifying agents in any JavaScript/TypeScript environment.\n * Useful for agent-to-agent verification, serverless functions, or custom integrations.\n *\n * @example\n * ```typescript\n * import { createClient } from '@astrasyncai/verification-gateway/sdk';\n *\n * const gateway = createClient({\n * apiBaseUrl: 'https://astrasync.ai/api',\n * });\n *\n * // Verify another agent before interacting\n * const result = await gateway.verify({\n * astraId: 'ASTRA-abc123',\n * purpose: 'data-exchange',\n * });\n *\n * if (result.identityVerified && result.policyAllowed && result.accessLevel !== 'none') {\n * // Safe to interact with this agent\n * }\n * ```\n */\n\nimport type {\n SDKOptions,\n AgentCredentials,\n VerificationResult,\n VerificationRequest,\n AccessLevel,\n GatewayConfig,\n} from '../types';\nimport { verify as coreVerify, quickVerify as coreQuickVerify, clearCache } from '../verify';\nimport { getTrustLevel, hasMinimumAccess, getCapabilities } from '../access-levels';\nimport type { AccessCapabilities } from '../access-levels';\n\n/**\n * Verification Gateway SDK Client\n */\nexport class VerificationGatewayClient {\n private config: GatewayConfig;\n private timeout: number;\n private retryConfig: { maxRetries: number; backoffMs: number };\n\n constructor(options: SDKOptions) {\n this.config = {\n apiBaseUrl: options.apiBaseUrl,\n apiKey: options.apiKey,\n defaultAccessLevel: options.defaultAccessLevel,\n minTrustScore: options.minTrustScore,\n minTrustScoreForFull: options.minTrustScoreForFull,\n cacheTtl: options.cacheTtl,\n debug: options.debug,\n customHeaders: options.customHeaders,\n counterpartyUrl: options.counterpartyUrl,\n counterpartyType: options.counterpartyType,\n };\n\n this.timeout = options.timeout || 10000;\n this.retryConfig = options.retry || { maxRetries: 3, backoffMs: 1000 };\n }\n\n /**\n * Full verification with all details\n */\n async verify(options: {\n astraId?: string;\n apiKey?: string;\n jwt?: string;\n purpose?: string;\n action?: string;\n resourceType?: string;\n resource?: string;\n jurisdiction?: string;\n transactionValue?: number;\n currency?: string;\n isSubAgentRequest?: boolean;\n parentAgentId?: string;\n subAgentDepth?: number;\n counterpartyUrl?: string;\n counterpartyType?: string;\n }): Promise<VerificationResult> {\n const credentials: AgentCredentials = {\n astraId: options.astraId,\n apiKey: options.apiKey,\n jwt: options.jwt,\n };\n\n return this.executeWithRetry(() =>\n coreVerify(this.config, {\n credentials,\n purpose: options.purpose,\n action: options.action,\n resourceType: options.resourceType,\n resource: options.resource,\n jurisdiction: options.jurisdiction,\n transactionValue: options.transactionValue,\n currency: options.currency,\n isSubAgentRequest: options.isSubAgentRequest,\n parentAgentId: options.parentAgentId,\n subAgentDepth: options.subAgentDepth,\n counterpartyUrl: options.counterpartyUrl,\n counterpartyType: options.counterpartyType as VerificationRequest['counterpartyType'],\n })\n );\n }\n\n /**\n * Quick verification — checks credentials and policy in one call.\n *\n * Round-18 G4: return shape mirrors `VerificationResult`'s identity/policy\n * split. Map to HTTP status the same way: `!identityVerified` → 401,\n * `identityVerified && !policyAllowed` → 403.\n */\n async quickVerify(credentials: { astraId?: string; apiKey?: string; jwt?: string }): Promise<{\n identityVerified: boolean;\n policyAllowed: boolean;\n accessLevel: AccessLevel;\n reason?: string;\n }> {\n return this.executeWithRetry(() => coreQuickVerify(this.config, credentials));\n }\n\n /**\n * Check if an agent has a specific access level\n */\n async hasAccess(\n credentials: { astraId?: string; apiKey?: string; jwt?: string },\n requiredLevel: AccessLevel\n ): Promise<boolean> {\n const result = await this.quickVerify(credentials);\n return hasMinimumAccess(result.accessLevel, requiredLevel);\n }\n\n /**\n * Get capabilities for a verified agent\n */\n async getCapabilities(credentials: {\n astraId?: string;\n apiKey?: string;\n jwt?: string;\n }): Promise<AccessCapabilities> {\n const result = await this.quickVerify(credentials);\n return getCapabilities(result.accessLevel);\n }\n\n /**\n * Verify a specific ASTRA-ID\n */\n async verifyAstraId(\n astraId: string,\n options?: {\n purpose?: string;\n action?: string;\n }\n ): Promise<VerificationResult> {\n return this.verify({\n astraId,\n purpose: options?.purpose,\n action: options?.action,\n });\n }\n\n /**\n * Verify using an API key\n */\n async verifyApiKey(\n apiKey: string,\n options?: {\n purpose?: string;\n action?: string;\n }\n ): Promise<VerificationResult> {\n return this.verify({\n apiKey,\n purpose: options?.purpose,\n action: options?.action,\n });\n }\n\n /**\n * Clear the verification cache\n */\n clearCache(): void {\n clearCache();\n }\n\n /**\n * Execute a function with retry logic\n */\n private async executeWithRetry<T>(fn: () => Promise<T>): Promise<T> {\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {\n try {\n // Add timeout\n const result = await Promise.race([\n fn(),\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('Request timeout')), this.timeout)\n ),\n ]);\n\n return result;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't retry on last attempt\n if (attempt < this.retryConfig.maxRetries) {\n // Exponential backoff\n const backoff = this.retryConfig.backoffMs * Math.pow(2, attempt);\n await new Promise((resolve) => setTimeout(resolve, backoff));\n }\n }\n }\n\n throw lastError || new Error('Verification failed after retries');\n }\n}\n\n/**\n * Create a new SDK client\n */\nexport function createClient(options: SDKOptions): VerificationGatewayClient {\n return new VerificationGatewayClient(options);\n}\n\n/**\n * One-shot verification without creating a client\n */\nexport async function verifyOnce(\n options: SDKOptions & {\n astraId?: string;\n apiKey?: string;\n jwt?: string;\n purpose?: string;\n action?: string;\n }\n): Promise<VerificationResult> {\n const client = createClient(options);\n return client.verify(options);\n}\n\n// Re-export utilities for convenience\nexport { getTrustLevel, hasMinimumAccess, getCapabilities };\n","/**\n * Cross-Protocol Transport Module\n *\n * Provides adapters for injecting/extracting AstraSync credentials\n * across HTTP, A2A, and MCP protocols.\n */\n\nimport type { AstraSyncCredentials, ProtocolTransport } from '../types';\nimport { setHttpHeaders, extractHttpCredentials } from './http';\nimport { setA2AMetadata, extractA2ACredentials } from './a2a';\nimport { setMcpMeta, extractMcpCredentials } from './mcp';\n\nexport { setHttpHeaders, extractHttpCredentials } from './http';\nexport { setA2AMetadata, extractA2ACredentials } from './a2a';\nexport { setMcpMeta, extractMcpCredentials } from './mcp';\n\n// Commerce protocol extractors + verifiers (PR 4+5)\nexport * from './purpose-mapping';\nexport * from './transaction-value';\nexport * from './rfc9421';\nexport * from './rfc9421-verify';\nexport * from './ucp';\nexport * from './acp';\nexport * from './vi';\nexport * from './stripe-webhook';\nexport * from './constraint-eval';\nexport * from './identity-binding';\nexport * from './ap2';\nexport * from './ap2-verify';\nexport * from './acp-verify';\nexport * from './mpp';\nexport * from './mpp-verify';\nexport * from './x402';\nexport * from './vi-verify';\nexport * from './commerce-pipeline';\nexport * from './extractor-registry';\nexport * from './registry/types';\nexport { createVisaRegistry } from './registry/visa';\nexport { createMastercardRegistry } from './registry/mastercard';\nexport { createWebBotAuthRegistry } from './registry/web-bot-auth';\n\n/**\n * Auto-detect protocol from request/context shape.\n */\nexport function detectProtocol(context: Record<string, unknown>): ProtocolTransport {\n // A2A: has metadata block with task-like structure\n if (context.metadata && typeof context.metadata === 'object') {\n return 'a2a';\n }\n\n // MCP: has _meta block (MCP convention)\n if (context._meta && typeof context._meta === 'object') {\n return 'mcp';\n }\n\n // Default to HTTP\n return 'http';\n}\n\n/**\n * Apply credentials to any protocol target.\n */\nexport function applyCredentials(\n protocol: ProtocolTransport,\n target: Record<string, unknown>,\n credentials: AstraSyncCredentials\n): Record<string, unknown> {\n switch (protocol) {\n case 'http':\n return setHttpHeaders(target as Record<string, string>, credentials);\n case 'a2a':\n return setA2AMetadata(target, credentials);\n case 'mcp':\n return setMcpMeta(target, credentials);\n default:\n return target;\n }\n}\n\n/**\n * Extract credentials from any protocol context.\n */\nexport function extractCredentialsFromProtocol(\n protocol: ProtocolTransport,\n context: Record<string, unknown>\n): AstraSyncCredentials | null {\n switch (protocol) {\n case 'http':\n return extractHttpCredentials(context as Record<string, string | string[] | undefined>);\n case 'a2a':\n return extractA2ACredentials(context);\n case 'mcp':\n return extractMcpCredentials(context);\n default:\n return null;\n }\n}\n","/**\n * A2A (Agent-to-Agent) Transport Adapter\n *\n * Maps AstraSync credentials to/from A2A task metadata.astrasync block.\n */\n\nimport type { AstraSyncCredentials } from '../types';\n\ninterface A2ATask {\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\ninterface AstraSyncMetadata {\n agentId: string;\n verifyUrl?: string;\n challengeUrl?: string;\n purpose?: { category: string; action?: string };\n duration?: { maxSessionDuration?: number };\n scope?: { jurisdiction?: string };\n}\n\n/**\n * Add AstraSync credentials to an A2A task's metadata block.\n */\nexport function setA2AMetadata(\n task: A2ATask,\n credentials: AstraSyncCredentials,\n): A2ATask {\n const astrasync: AstraSyncMetadata = {\n agentId: credentials.agentId,\n };\n\n if (credentials.verifyUrl) astrasync.verifyUrl = credentials.verifyUrl;\n if (credentials.challengeUrl) astrasync.challengeUrl = credentials.challengeUrl;\n if (credentials.pdlss?.purpose) astrasync.purpose = credentials.pdlss.purpose;\n if (credentials.pdlss?.duration) astrasync.duration = credentials.pdlss.duration;\n if (credentials.pdlss?.scope) astrasync.scope = credentials.pdlss.scope;\n\n return {\n ...task,\n metadata: {\n ...task.metadata,\n astrasync,\n },\n };\n}\n\n/**\n * Extract AstraSync credentials from an A2A task's metadata block.\n */\nexport function extractA2ACredentials(task: A2ATask): AstraSyncCredentials | null {\n const meta = task.metadata?.astrasync as AstraSyncMetadata | undefined;\n if (!meta?.agentId) return null;\n\n const credentials: AstraSyncCredentials = {\n agentId: meta.agentId,\n };\n\n if (meta.verifyUrl) credentials.verifyUrl = meta.verifyUrl;\n if (meta.challengeUrl) credentials.challengeUrl = meta.challengeUrl;\n\n if (meta.purpose || meta.duration || meta.scope) {\n credentials.pdlss = {};\n if (meta.purpose) credentials.pdlss.purpose = meta.purpose;\n if (meta.duration) credentials.pdlss.duration = meta.duration;\n if (meta.scope) credentials.pdlss.scope = meta.scope;\n }\n\n return credentials;\n}\n","/**\n * MCP (Model Context Protocol) Transport Adapter\n *\n * Maps AstraSync credentials to/from MCP params._meta.astrasync block.\n */\n\nimport type { AstraSyncCredentials } from '../types';\n\ninterface McpParams {\n _meta?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\ninterface AstraSyncMeta {\n agentId: string;\n verifyUrl?: string;\n challengeUrl?: string;\n purpose?: { category: string; action?: string };\n duration?: { maxSessionDuration?: number };\n scope?: { jurisdiction?: string };\n}\n\n/**\n * Add AstraSync credentials to MCP params' _meta block.\n */\nexport function setMcpMeta(\n params: McpParams,\n credentials: AstraSyncCredentials,\n): McpParams {\n const astrasync: AstraSyncMeta = {\n agentId: credentials.agentId,\n };\n\n if (credentials.verifyUrl) astrasync.verifyUrl = credentials.verifyUrl;\n if (credentials.challengeUrl) astrasync.challengeUrl = credentials.challengeUrl;\n if (credentials.pdlss?.purpose) astrasync.purpose = credentials.pdlss.purpose;\n if (credentials.pdlss?.duration) astrasync.duration = credentials.pdlss.duration;\n if (credentials.pdlss?.scope) astrasync.scope = credentials.pdlss.scope;\n\n return {\n ...params,\n _meta: {\n ...params._meta,\n astrasync,\n },\n };\n}\n\n/**\n * Extract AstraSync credentials from MCP params' _meta block.\n */\nexport function extractMcpCredentials(params: McpParams): AstraSyncCredentials | null {\n const meta = params._meta?.astrasync as AstraSyncMeta | undefined;\n if (!meta?.agentId) return null;\n\n const credentials: AstraSyncCredentials = {\n agentId: meta.agentId,\n };\n\n if (meta.verifyUrl) credentials.verifyUrl = meta.verifyUrl;\n if (meta.challengeUrl) credentials.challengeUrl = meta.challengeUrl;\n\n if (meta.purpose || meta.duration || meta.scope) {\n credentials.pdlss = {};\n if (meta.purpose) credentials.pdlss.purpose = meta.purpose;\n if (meta.duration) credentials.pdlss.duration = meta.duration;\n if (meta.scope) credentials.pdlss.scope = meta.scope;\n }\n\n return credentials;\n}\n","/**\n * Protocol request -> AstraSync PDLSS purpose category mapping.\n *\n * Per spec v2.6 §7.4.3 commerce purpose mapping table, extended with MPP + x402\n * entries (April 2026 protocol landscape).\n */\n\nexport type CommercePurpose =\n | 'commerce.checkout.create'\n | 'commerce.checkout.update'\n | 'commerce.checkout.confirm'\n | 'commerce.checkout.cancel'\n | 'commerce.payment.execute'\n | 'commerce.payment.stream'\n | 'commerce.delegation.intent'\n | 'commerce.delegation.checkout'\n | 'commerce.delegation.payment'\n | 'commerce.identity_probe'\n | 'commerce.browsing';\n\nconst UCP_ROUTES: Array<{ method: string; pattern: RegExp; purpose: CommercePurpose }> = [\n { method: 'POST', pattern: /^\\/checkout[-_]sessions\\/?$/, purpose: 'commerce.checkout.create' },\n {\n method: 'PUT',\n pattern: /^\\/checkout[-_]sessions\\/[^/]+\\/?$/,\n purpose: 'commerce.checkout.update',\n },\n {\n method: 'POST',\n pattern: /^\\/checkout[-_]sessions\\/[^/]+\\/complete\\/?$/,\n purpose: 'commerce.payment.execute',\n },\n {\n method: 'POST',\n pattern: /^\\/checkout[-_]sessions\\/[^/]+\\/cancel\\/?$/,\n purpose: 'commerce.checkout.cancel',\n },\n];\n\nconst ACP_ROUTES: Array<{ method: string; pattern: RegExp; purpose: CommercePurpose }> = [\n { method: 'POST', pattern: /^\\/checkout_sessions\\/?$/, purpose: 'commerce.checkout.create' },\n {\n method: 'POST',\n pattern: /^\\/checkout_sessions\\/[^/]+\\/?$/,\n purpose: 'commerce.checkout.update',\n },\n {\n method: 'POST',\n pattern: /^\\/checkout_sessions\\/[^/]+\\/complete\\/?$/,\n purpose: 'commerce.payment.execute',\n },\n {\n method: 'POST',\n pattern: /^\\/checkout_sessions\\/[^/]+\\/cancel\\/?$/,\n purpose: 'commerce.checkout.cancel',\n },\n {\n method: 'POST',\n pattern: /^\\/agentic_commerce\\/delegate_payment\\/?$/,\n purpose: 'commerce.delegation.payment',\n },\n];\n\nexport function mapUCPRequestToPurpose(method: string, path: string): CommercePurpose | null {\n const normalizedMethod = method.toUpperCase();\n const normalizedPath = stripQuery(path);\n for (const route of UCP_ROUTES) {\n if (route.method === normalizedMethod && route.pattern.test(normalizedPath)) {\n return route.purpose;\n }\n }\n return null;\n}\n\nexport function mapACPRequestToPurpose(method: string, path: string): CommercePurpose | null {\n const normalizedMethod = method.toUpperCase();\n const normalizedPath = stripQuery(path);\n for (const route of ACP_ROUTES) {\n if (route.method === normalizedMethod && route.pattern.test(normalizedPath)) {\n return route.purpose;\n }\n }\n return null;\n}\n\nexport type AP2MandateType = 'intent_mandate' | 'cart_mandate' | 'payment_mandate';\nexport function mapAP2MandateToPurpose(mandateType: AP2MandateType): CommercePurpose {\n switch (mandateType) {\n case 'intent_mandate':\n return 'commerce.delegation.intent';\n case 'cart_mandate':\n return 'commerce.checkout.confirm';\n case 'payment_mandate':\n return 'commerce.payment.execute';\n }\n}\n\nexport type VIMandateType = 'checkout' | 'payment' | 'checkout.open' | 'payment.open';\nexport function mapVIMandateToPurpose(mandateType: VIMandateType): CommercePurpose {\n switch (mandateType) {\n case 'checkout':\n return 'commerce.checkout.confirm';\n case 'payment':\n return 'commerce.payment.execute';\n case 'checkout.open':\n return 'commerce.delegation.checkout';\n case 'payment.open':\n return 'commerce.delegation.payment';\n }\n}\n\nexport type RFC9421Tag = 'browse' | 'purchase' | undefined;\nexport function mapRFC9421TagToPurpose(tag: RFC9421Tag): CommercePurpose {\n if (tag === 'purchase') return 'commerce.payment.execute';\n return 'commerce.browsing';\n}\n\nexport type MPPIntent = 'charge' | 'session';\nexport function mapMPPRequestToPurpose(\n intent: MPPIntent | undefined,\n amount: number | undefined\n): CommercePurpose {\n if (typeof amount === 'number' && amount === 0) return 'commerce.identity_probe';\n if (intent === 'session') return 'commerce.payment.stream';\n return 'commerce.payment.execute';\n}\n\nexport function mapX402RequestToPurpose(amount: number | undefined): CommercePurpose {\n if (typeof amount === 'number' && amount === 0) return 'commerce.identity_probe';\n return 'commerce.payment.execute';\n}\n\nfunction stripQuery(path: string): string {\n const q = path.indexOf('?');\n return q === -1 ? path : path.slice(0, q);\n}\n\n/**\n * Informational Stripe webhook events surfaced as trust signals on\n * `CommerceContext.trustSignals` but NOT routed to a PDLSS purpose.\n */\nexport const STRIPE_WEBHOOK_INFORMATIONAL_EVENTS = [\n 'payment_intent.succeeded',\n 'payment_intent.payment_failed',\n 'charge.refunded',\n 'checkout.session.completed',\n 'customer.subscription.created',\n] as const;\nexport type StripeWebhookInformationalEvent = (typeof STRIPE_WEBHOOK_INFORMATIONAL_EVENTS)[number];\n\nexport function isStripeWebhookInformational(eventType: string): boolean {\n return (STRIPE_WEBHOOK_INFORMATIONAL_EVENTS as readonly string[]).includes(eventType);\n}\n","/**\n * Per-protocol transaction-value normalization.\n *\n * Each protocol encodes amount/currency differently. This module produces a\n * uniform `TransactionValueContext` with `source` recording the extraction\n * path so trace logs can show where the value came from.\n *\n * Amount unit: \"major units\" (dollars/euros/etc. for fiat; native unit for\n * tokens — we do NOT convert across currencies). UCP/ACP totals are in\n * cents, so we divide by 100. MPP/x402/VI pass through as declared.\n */\n\nexport interface TransactionValueContext {\n protocol: 'vi' | 'ap2' | 'ucp' | 'acp' | 'mpp' | 'x402' | 'agentpay' | 'tap';\n amount: number;\n currency: string;\n source: string;\n}\n\nexport function extractUCPTransactionValue(input: {\n totals?: Array<{ type?: string; amount?: number; currency?: string }>;\n}): TransactionValueContext | null {\n const totals = input.totals ?? [];\n const total = totals.find((t) => t.type === 'total') ?? totals[0];\n if (!total || typeof total.amount !== 'number' || !total.currency) return null;\n return {\n protocol: 'ucp',\n amount: total.amount / 100,\n currency: total.currency,\n source: `totals[type=${total.type ?? 'unknown'}].amount`,\n };\n}\n\nexport function extractACPTransactionValue(input: {\n totals?: Array<{ type?: string; amount?: number; currency?: string }>;\n}): TransactionValueContext | null {\n const totals = input.totals ?? [];\n const total = totals.find((t) => t.type === 'total') ?? totals[0];\n if (!total || typeof total.amount !== 'number' || !total.currency) return null;\n return {\n protocol: 'acp',\n amount: total.amount / 100,\n currency: total.currency,\n source: `totals[type=${total.type ?? 'unknown'}].amount`,\n };\n}\n\nexport interface VIClaimsForValue {\n constraints?: {\n paymentAmount?: { currency?: string; min?: number; max?: number };\n };\n l3aPaymentAmount?: { currency?: string; amount?: number };\n}\n\nexport function extractVITransactionValue(\n claims: VIClaimsForValue\n): TransactionValueContext | null {\n const l3a = claims.l3aPaymentAmount;\n if (l3a && typeof l3a.amount === 'number' && l3a.currency) {\n return {\n protocol: 'vi',\n amount: l3a.amount,\n currency: l3a.currency,\n source: 'L3a.payment.amount',\n };\n }\n const bound = claims.constraints?.paymentAmount;\n if (bound && typeof bound.max === 'number' && bound.currency) {\n return {\n protocol: 'vi',\n amount: bound.max,\n currency: bound.currency,\n source: 'L2.payment.constraints.amount.max',\n };\n }\n return null;\n}\n\nexport interface AP2PaymentMandateForValue {\n payment_details_total?: { amount?: { value?: string | number; currency?: string } };\n}\n\nexport function extractAP2TransactionValue(\n mandate: AP2PaymentMandateForValue | undefined\n): TransactionValueContext | null {\n const amt = mandate?.payment_details_total?.amount;\n if (!amt || !amt.currency) return null;\n const n = typeof amt.value === 'string' ? Number(amt.value) : amt.value;\n if (typeof n !== 'number' || !Number.isFinite(n)) return null;\n return {\n protocol: 'ap2',\n amount: n,\n currency: amt.currency,\n source: 'payment_mandate.payment_details_total.amount',\n };\n}\n\nexport interface MPPChallengeForValue {\n method?: string;\n request?: { amount?: number; currency?: string } & Record<string, unknown>;\n}\n\nexport function extractMPPTransactionValue(\n challenge: MPPChallengeForValue\n): TransactionValueContext | null {\n const req = challenge.request;\n if (!req || typeof req.amount !== 'number' || !req.currency) return null;\n return {\n protocol: 'mpp',\n amount: req.amount,\n currency: req.currency,\n source: `challenge.request.amount (method=${challenge.method ?? 'unknown'})`,\n };\n}\n\nexport interface X402RequestForValue {\n maxAmountRequired?: number;\n amount?: number;\n asset?: string;\n currency?: string;\n}\n\nexport function extractX402TransactionValue(\n req: X402RequestForValue\n): TransactionValueContext | null {\n const amount = req.maxAmountRequired ?? req.amount;\n const currency = req.currency ?? req.asset;\n if (typeof amount !== 'number' || !currency) return null;\n return {\n protocol: 'x402',\n amount,\n currency,\n source: req.maxAmountRequired !== undefined ? 'maxAmountRequired' : 'amount',\n };\n}\n","/**\n * RFC 9421 HTTP Message Signatures parser.\n *\n * Wraps `structured-headers` (transitive dep of http-message-signatures) to\n * parse the Signature-Input and Signature Dictionary headers per RFC 9421 §2.\n *\n * Produces structured metadata (kid, algorithm, covered components, tag,\n * created/expires/nonce, signature bytes) without verifying the signature —\n * verification lives in rfc9421-verify.ts.\n *\n * Shared by:\n * - Agent Pay (Mastercard) — kid resolves via Mastercard Agent Registry\n * - TAP (Visa) — kid resolves via Visa JWKS\n * - Web Bot Auth (generic transport substrate) — kid resolves via\n * /.well-known/http-message-signatures-directory\n */\n\nimport { parseDictionary } from 'structured-headers';\n\nexport interface RFC9421SignatureParams {\n /** The label identifying the signature in the Dictionary header (e.g. \"sig1\"). */\n label: string;\n /** Key ID used to look up the verifying key in the relevant registry. */\n kid: string;\n /** Algorithm declared in the Signature-Input params (e.g. \"ecdsa-p256-sha256\", \"ed25519\"). */\n alg?: string;\n /** Covered components, in order, per RFC 9421 §2.1. */\n covered: string[];\n /** Base64url-encoded signature bytes extracted from the paired Signature header. */\n signatureBase64: string;\n /** Unix seconds when the signature was created. */\n created?: number;\n /** Unix seconds when the signature expires. */\n expires?: number;\n /** Nonce (opaque string) for replay protection. */\n nonce?: string;\n /** Tag parameter. For Agent Pay/TAP this is \"browse\" or \"purchase\"; undefined otherwise. */\n tag?: 'browse' | 'purchase' | string;\n}\n\nexport interface ParsedRFC9421 {\n signatures: RFC9421SignatureParams[];\n}\n\n/**\n * Parse the RFC 9421 Signature-Input and Signature headers from a request or response.\n * Returns all signatures present (a single message may carry multiple labelled signatures).\n *\n * Returns null if either header is missing or malformed.\n */\nexport function parseRFC9421(\n headers: Record<string, string | string[] | undefined>\n): ParsedRFC9421 | null {\n const sigInput = readHeader(headers, 'signature-input');\n const sig = readHeader(headers, 'signature');\n if (!sigInput || !sig) return null;\n\n let inputDict;\n let sigDict;\n try {\n inputDict = parseDictionary(sigInput);\n sigDict = parseDictionary(sig);\n } catch {\n return null;\n }\n\n const signatures: RFC9421SignatureParams[] = [];\n\n for (const [label, entry] of inputDict) {\n // entry.value is the inner list of covered components; entry[1] is the params Map.\n const innerList = Array.isArray(entry)\n ? entry[0]\n : (entry as { value?: unknown; params?: unknown }).value;\n const params = Array.isArray(entry)\n ? entry[1]\n : (entry as { value?: unknown; params?: unknown }).params;\n if (!Array.isArray(innerList) || !params) continue;\n\n const covered: string[] = [];\n for (const item of innerList as Array<[unknown, Map<string, unknown>]>) {\n const [bare] = Array.isArray(item) ? item : [item];\n if (typeof bare === 'string') covered.push(bare);\n else if (bare && typeof bare === 'object' && 'toString' in bare) covered.push(String(bare));\n }\n\n const paramsMap = params as Map<string, unknown>;\n const kid = coerceString(paramsMap.get('keyid'));\n if (!kid) continue;\n\n const sigEntry = sigDict.get(label);\n if (!sigEntry) continue;\n\n const sigBare = Array.isArray(sigEntry) ? sigEntry[0] : (sigEntry as { value?: unknown }).value;\n const signatureBase64 = extractBase64(sigBare);\n if (!signatureBase64) continue;\n\n signatures.push({\n label,\n kid,\n alg: coerceString(paramsMap.get('alg')),\n covered,\n signatureBase64,\n created: coerceNumber(paramsMap.get('created')),\n expires: coerceNumber(paramsMap.get('expires')),\n nonce: coerceString(paramsMap.get('nonce')),\n tag: coerceString(paramsMap.get('tag')),\n });\n }\n\n if (signatures.length === 0) return null;\n return { signatures };\n}\n\nfunction readHeader(\n headers: Record<string, string | string[] | undefined>,\n name: string\n): string | null {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === name) {\n const raw = headers[key];\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw.join(', ');\n return null;\n }\n }\n return null;\n}\n\nfunction coerceString(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (value == null) return undefined;\n if (typeof value === 'object' && 'toString' in (value as object)) {\n const s = String(value);\n return s.length > 0 ? s : undefined;\n }\n return undefined;\n}\n\nfunction coerceNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'bigint') return Number(value);\n return undefined;\n}\n\nfunction extractBase64(value: unknown): string | null {\n if (value instanceof Uint8Array) return bufferToBase64(value);\n if (value instanceof ArrayBuffer) return bufferToBase64(new Uint8Array(value));\n if (ArrayBuffer.isView(value)) {\n const v = value as ArrayBufferView;\n return bufferToBase64(new Uint8Array(v.buffer, v.byteOffset, v.byteLength));\n }\n if (typeof value === 'string') {\n if (value.startsWith(':') && value.endsWith(':')) return value.slice(1, -1);\n return value;\n }\n return null;\n}\n\nfunction bufferToBase64(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString('base64');\n}\n","/**\n * RFC 9421 HTTP Message Signatures verification.\n *\n * Wraps http-message-signatures (dhensby) verifyMessage() with a RegistryResolver\n * hook for kid → JWK lookup. Library handles canonicalization + ES256/EdDSA/\n * HMAC/RSA verification; we supply the key-finding callback and policy around\n * clock skew.\n *\n * Shared by:\n * - Agent Pay (Mastercard) — resolver = createMastercardRegistry\n * - TAP (Visa) — resolver = createVisaRegistry\n * - Web Bot Auth (generic) — resolver = createWebBotAuthRegistry\n */\n\nimport { httpbis, type VerifierFinder, type VerifyingKey } from 'http-message-signatures';\nimport type { JWK } from 'jose';\nimport type { RegistryResolver } from './registry/types';\n\nexport interface RFC9421VerifyRequest {\n method: string;\n url: string;\n headers: Record<string, string | string[]>;\n body?: string;\n}\n\nexport interface RFC9421VerifyOptions {\n resolver: RegistryResolver;\n /** Seconds of tolerance around created/expires. Default 300. */\n clockSkewSec?: number;\n /** Injectable for deterministic tests. */\n now?: () => number;\n}\n\nexport interface RFC9421VerifyResult {\n ok: boolean;\n kid?: string;\n registry?: RegistryResolver['name'];\n algorithm?: string;\n error?: string;\n}\n\nexport async function verifyRFC9421(\n request: RFC9421VerifyRequest,\n options: RFC9421VerifyOptions\n): Promise<RFC9421VerifyResult> {\n const { resolver } = options;\n const tolerance = options.clockSkewSec ?? 300;\n const nowSec = options.now ? options.now() : Math.floor(Date.now() / 1000);\n\n let resolvedKid: string | undefined;\n let resolvedAlg: string | undefined;\n\n const keyLookup: VerifierFinder = async (parameters) => {\n const kid = typeof parameters.keyid === 'string' ? parameters.keyid : undefined;\n if (!kid) return null;\n resolvedKid = kid;\n const alg = typeof parameters.alg === 'string' ? parameters.alg : undefined;\n if (alg) resolvedAlg = alg;\n\n const origin = safeOrigin(request.url);\n const jwk = await resolver.resolve(kid, { origin, algorithm: alg });\n if (!jwk) return null;\n\n // Check clock-skew on this specific signature's created/expires.\n // SignatureParameters may carry Date, number, or ISO string per library.\n const created = toUnixSeconds(parameters.created);\n const expires = toUnixSeconds(parameters.expires);\n if (created !== undefined && Math.abs(nowSec - created) > tolerance) return null;\n if (expires !== undefined && nowSec > expires + tolerance) return null;\n\n return jwkToVerifyingKey(kid, jwk, alg);\n };\n\n try {\n const result = await httpbis.verifyMessage(\n {\n keyLookup,\n },\n normalizeRequest(request)\n );\n if (result === true) {\n return {\n ok: true,\n kid: resolvedKid,\n registry: resolver.name,\n algorithm: resolvedAlg,\n };\n }\n return {\n ok: false,\n kid: resolvedKid,\n registry: resolver.name,\n algorithm: resolvedAlg,\n error: result === false ? 'signature invalid' : 'no signature found',\n };\n } catch (err) {\n return {\n ok: false,\n kid: resolvedKid,\n registry: resolver.name,\n algorithm: resolvedAlg,\n error: err instanceof Error ? err.message : 'verification error',\n };\n }\n}\n\nfunction normalizeRequest(request: RFC9421VerifyRequest): {\n method: string;\n url: string;\n headers: Record<string, string | string[]>;\n} {\n return {\n method: request.method.toUpperCase(),\n url: request.url,\n headers: request.headers,\n };\n}\n\nfunction safeOrigin(url: string): string | undefined {\n try {\n return new URL(url).origin;\n } catch {\n return undefined;\n }\n}\n\nasync function jwkToVerifyingKey(\n id: string,\n jwk: JWK,\n alg: string | undefined\n): Promise<VerifyingKey> {\n const algorithm = alg ?? inferAlgFromJwk(jwk);\n const { subtle } = await getCrypto();\n const importAlg = webCryptoImportAlgFor(algorithm);\n const verifyAlg = webCryptoAlgFor(algorithm);\n if (!importAlg || !verifyAlg) {\n return {\n id,\n algs: alg ? [alg] : undefined,\n verify: async () => false,\n };\n }\n const key = await subtle.importKey('jwk', jwk as JsonWebKey, importAlg, false, ['verify']);\n\n return {\n id,\n algs: alg ? [alg] : undefined,\n verify: async (data: Buffer, signature: Buffer): Promise<boolean> => {\n try {\n return await subtle.verify(verifyAlg, key, toArrayBuffer(signature), toArrayBuffer(data));\n } catch {\n return false;\n }\n },\n };\n}\n\nfunction inferAlgFromJwk(jwk: JWK): string {\n if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519') return 'ed25519';\n if (jwk.kty === 'EC' && jwk.crv === 'P-256') return 'ecdsa-p256-sha256';\n if (jwk.kty === 'EC' && jwk.crv === 'P-384') return 'ecdsa-p384-sha384';\n if (jwk.kty === 'RSA') return 'rsa-v1_5-sha256';\n return 'ecdsa-p256-sha256';\n}\n\nfunction webCryptoAlgFor(\n rfc9421Alg: string\n): AlgorithmIdentifier | EcdsaParams | RsaPssParams | null {\n switch (rfc9421Alg) {\n case 'ed25519':\n return { name: 'Ed25519' };\n case 'ecdsa-p256-sha256':\n return { name: 'ECDSA', hash: 'SHA-256' };\n case 'ecdsa-p384-sha384':\n return { name: 'ECDSA', hash: 'SHA-384' };\n case 'rsa-v1_5-sha256':\n return { name: 'RSASSA-PKCS1-v1_5' };\n case 'rsa-pss-sha512':\n return { name: 'RSA-PSS', saltLength: 64 };\n default:\n return null;\n }\n}\n\nfunction webCryptoImportAlgFor(\n rfc9421Alg: string\n): AlgorithmIdentifier | EcKeyImportParams | RsaHashedImportParams | null {\n switch (rfc9421Alg) {\n case 'ed25519':\n return { name: 'Ed25519' };\n case 'ecdsa-p256-sha256':\n return { name: 'ECDSA', namedCurve: 'P-256' };\n case 'ecdsa-p384-sha384':\n return { name: 'ECDSA', namedCurve: 'P-384' };\n case 'rsa-v1_5-sha256':\n return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' };\n case 'rsa-pss-sha512':\n return { name: 'RSA-PSS', hash: 'SHA-512' };\n default:\n return null;\n }\n}\n\nfunction toArrayBuffer(buf: Buffer): ArrayBuffer {\n const out = new ArrayBuffer(buf.byteLength);\n new Uint8Array(out).set(buf);\n return out;\n}\n\nfunction toUnixSeconds(v: unknown): number | undefined {\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (v instanceof Date) return Math.floor(v.getTime() / 1000);\n if (typeof v === 'string') {\n const parsed = Date.parse(v);\n if (Number.isFinite(parsed)) return Math.floor(parsed / 1000);\n }\n return undefined;\n}\n\nasync function getCrypto(): Promise<{ subtle: SubtleCrypto }> {\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n return { subtle: globalThis.crypto.subtle };\n }\n // Node fallback\n const nodeCrypto = await import('node:crypto');\n return { subtle: nodeCrypto.webcrypto.subtle as SubtleCrypto };\n}\n","/**\n * UCP (Universal Commerce Protocol) checkout session extractor.\n *\n * Google + Shopify spec (ucp.dev). Extracts checkout session context from\n * incoming HTTP requests and, at registration time, validates the\n * `/.well-known/ucp` manifest via AJV against the mirrored JSON schema.\n */\n\nimport { mapUCPRequestToPurpose, type CommercePurpose } from './purpose-mapping';\n\nexport interface UCPTotal {\n type?: string;\n amount?: number;\n currency?: string;\n}\n\nexport interface UCPCheckoutContext {\n sessionId?: string;\n endpoint: string;\n purpose: CommercePurpose | null;\n merchantDomain?: string;\n totals?: UCPTotal[];\n paymentMethod?: string;\n manifestUrl?: string;\n}\n\nexport interface UCPRequestLike {\n method: string;\n url: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n}\n\nexport function extractUCPContext(request: UCPRequestLike): UCPCheckoutContext | null {\n const { method, url } = request;\n if (!method || !url) return null;\n\n const parsedUrl = safeParseUrl(url);\n const path = parsedUrl?.pathname ?? url.split('?')[0];\n\n const purpose = mapUCPRequestToPurpose(method, path);\n const endpoint = `${method.toUpperCase()} ${path}`;\n const sessionId = extractSessionId(path);\n\n const body = (request.body ?? {}) as Record<string, unknown>;\n const totals = Array.isArray(body.totals) ? (body.totals as UCPTotal[]) : undefined;\n const paymentMethod = coerceString(body.payment_method ?? body.paymentMethod);\n const manifestUrl = coerceString(body.manifest_url ?? body.manifestUrl);\n\n const merchantDomain = extractMerchantDomain(body, parsedUrl);\n\n return {\n sessionId,\n endpoint,\n purpose,\n merchantDomain,\n totals,\n paymentMethod,\n manifestUrl,\n };\n}\n\n/**\n * Fetch and parse a UCP manifest at registration time. Returns parsed JSON\n * on success, null on any failure (network, parse, timeout). Does NOT throw.\n *\n * Schema validation is a separate step — see `validateUCPManifest`.\n */\nexport async function fetchUCPManifest(\n manifestUrl: string,\n options: { timeoutMs?: number } = {}\n): Promise<unknown | null> {\n const timeoutMs = options.timeoutMs ?? 3000;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(manifestUrl, { signal: controller.signal });\n if (!res.ok) return null;\n return await res.json();\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Validate a UCP manifest against the minimal shape we care about.\n *\n * The full UCP manifest schema lives upstream (ucp.dev) and is out of scope\n * to mirror here exhaustively. This function checks the structural guarantees\n * we depend on: required top-level fields (version, capabilities, endpoints).\n *\n * For full schema validation, consumers can pass their own AJV compiled\n * validator via `options.validator`.\n */\nexport interface UCPManifestValidationResult {\n ok: boolean;\n errors: string[];\n}\n\nexport function validateUCPManifest(\n manifest: unknown,\n options: { validator?: (m: unknown) => { ok: boolean; errors: string[] } } = {}\n): UCPManifestValidationResult {\n if (options.validator) return options.validator(manifest);\n\n const errors: string[] = [];\n if (!manifest || typeof manifest !== 'object') {\n return { ok: false, errors: ['manifest is not an object'] };\n }\n const m = manifest as Record<string, unknown>;\n if (typeof m.version !== 'string') errors.push('version is required and must be a string');\n if (!Array.isArray(m.capabilities)) errors.push('capabilities must be an array');\n if (!m.endpoints || typeof m.endpoints !== 'object') errors.push('endpoints must be an object');\n return { ok: errors.length === 0, errors };\n}\n\nfunction safeParseUrl(url: string): URL | null {\n try {\n return new URL(url, 'http://placeholder.invalid');\n } catch {\n return null;\n }\n}\n\nfunction extractSessionId(path: string): string | undefined {\n const match = path.match(/\\/checkout[-_]sessions\\/([^/?#]+)/);\n return match?.[1];\n}\n\nfunction extractMerchantDomain(\n body: Record<string, unknown>,\n parsedUrl: URL | null\n): string | undefined {\n const explicit = coerceString(body.merchant_domain ?? body.merchantDomain);\n if (explicit) return explicit;\n if (parsedUrl && parsedUrl.hostname !== 'placeholder.invalid') return parsedUrl.hostname;\n return undefined;\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n","/**\n * ACP (Agentic Commerce Protocol) request extractor.\n *\n * Co-maintained by OpenAI + Stripe. Spec at agenticcommerce.dev.\n *\n * Extracts ACP request context from HTTP requests:\n * - Multi-header parsing: Signature, Timestamp, Idempotency-Key,\n * Authorization: Bearer, API-Version\n * - Endpoint classification: Agentic Checkout (checkout_sessions.*) vs\n * Delegate Payment (agentic_commerce/delegate_payment)\n * - Payment token detection: spt_* (Stripe SharedPaymentToken),\n * vt_* (ACP vault token), unknown\n * - Totals + merchant extraction from body\n *\n * No signature verification here — see acp-verify.ts.\n */\n\nimport { mapACPRequestToPurpose, type CommercePurpose } from './purpose-mapping';\n\nexport type ACPEndpoint =\n | 'checkout_sessions.create'\n | 'checkout_sessions.update'\n | 'checkout_sessions.complete'\n | 'checkout_sessions.cancel'\n | 'delegate_payment'\n | 'unknown';\n\nexport type ACPPaymentTokenType = 'stripe-spt' | 'acp-vt' | 'other' | null;\n\nexport interface ACPTotal {\n type?: string;\n amount?: number;\n currency?: string;\n}\n\nexport interface ACPRequestContext {\n endpoint: ACPEndpoint;\n purpose: CommercePurpose | null;\n sessionId?: string;\n merchantId?: string;\n apiVersion?: string;\n bearer?: string;\n signatureHeader?: string;\n timestampHeader?: string;\n idempotencyKey?: string;\n paymentToken?: {\n raw?: string;\n type: ACPPaymentTokenType;\n provider?: string;\n };\n totals?: ACPTotal[];\n fulfillmentOption?: string;\n rawBody?: string;\n}\n\nexport interface ACPRequestLike {\n method: string;\n url: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n}\n\nexport function extractACPContext(request: ACPRequestLike): ACPRequestContext | null {\n const { method, url } = request;\n if (!method || !url) return null;\n\n const path = stripQuery(url.startsWith('http') ? new URL(url).pathname : url);\n\n const endpoint = classifyEndpoint(method, path);\n const purpose = mapACPRequestToPurpose(method, path);\n const sessionId = extractSessionId(path);\n\n const headers = request.headers ?? {};\n const signatureHeader = readHeader(headers, 'signature');\n const timestampHeader = readHeader(headers, 'timestamp');\n const idempotencyKey = readHeader(headers, 'idempotency-key');\n const apiVersion = readHeader(headers, 'api-version');\n const bearer = extractBearer(readHeader(headers, 'authorization'));\n\n const body = (request.body ?? {}) as Record<string, unknown>;\n const merchantId = coerceString(body.merchant_id ?? body.merchantId);\n const totals = Array.isArray(body.totals) ? (body.totals as ACPTotal[]) : undefined;\n const fulfillmentOption = extractFulfillmentOption(body);\n\n const paymentToken = extractPaymentToken(body);\n\n return {\n endpoint,\n purpose,\n sessionId,\n merchantId,\n apiVersion,\n bearer,\n signatureHeader,\n timestampHeader,\n idempotencyKey,\n paymentToken,\n totals,\n fulfillmentOption,\n rawBody: request.rawBody,\n };\n}\n\nfunction classifyEndpoint(method: string, path: string): ACPEndpoint {\n const m = method.toUpperCase();\n if (m !== 'POST') return 'unknown';\n if (/^\\/agentic_commerce\\/delegate_payment\\/?$/.test(path)) return 'delegate_payment';\n if (/^\\/checkout_sessions\\/?$/.test(path)) return 'checkout_sessions.create';\n if (/^\\/checkout_sessions\\/[^/]+\\/?$/.test(path)) return 'checkout_sessions.update';\n if (/^\\/checkout_sessions\\/[^/]+\\/complete\\/?$/.test(path)) return 'checkout_sessions.complete';\n if (/^\\/checkout_sessions\\/[^/]+\\/cancel\\/?$/.test(path)) return 'checkout_sessions.cancel';\n return 'unknown';\n}\n\nfunction extractSessionId(path: string): string | undefined {\n const match = path.match(/\\/checkout_sessions\\/([^/?#]+)/);\n return match?.[1];\n}\n\nfunction extractBearer(authHeader: string | undefined): string | undefined {\n if (!authHeader) return undefined;\n const match = authHeader.match(/^Bearer\\s+(.+)$/i);\n return match ? match[1].trim() : undefined;\n}\n\nfunction extractPaymentToken(body: Record<string, unknown>): ACPRequestContext['paymentToken'] {\n const paymentData = body.payment_data as Record<string, unknown> | undefined;\n if (!paymentData) return undefined;\n const raw = coerceString(paymentData.token);\n const provider = coerceString(paymentData.provider);\n if (!raw) return { raw: undefined, type: null, provider };\n const type = classifyPaymentToken(raw);\n return { raw, type, provider };\n}\n\nfunction classifyPaymentToken(token: string): ACPPaymentTokenType {\n if (token.startsWith('spt_')) return 'stripe-spt';\n if (token.startsWith('vt_')) return 'acp-vt';\n return 'other';\n}\n\nfunction extractFulfillmentOption(body: Record<string, unknown>): string | undefined {\n const direct = coerceString(body.fulfillment_option ?? body.fulfillmentOption);\n if (direct) return direct;\n const options = body.fulfillment_options;\n if (Array.isArray(options) && options.length > 0) {\n const first = options[0];\n if (first && typeof first === 'object') {\n const id = coerceString((first as Record<string, unknown>).id);\n if (id) return id;\n }\n }\n return undefined;\n}\n\nfunction readHeader(\n headers: Record<string, string | string[] | undefined>,\n name: string\n): string | undefined {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === name) {\n const raw = headers[key];\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw[0];\n }\n }\n return undefined;\n}\n\nfunction stripQuery(path: string): string {\n const q = path.indexOf('?');\n return q === -1 ? path : path.slice(0, q);\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n","/**\n * VI (Verifiable Intent) SD-JWT extraction.\n *\n * Open-sourced 5 March 2026 by Mastercard + Google (v0.1-draft).\n * VI is a 3-layer SD-JWT chain:\n * L1 — issuer → wallet (credential provider)\n * L2 — user → agent (cnf.jwk binding to L3 agent key)\n * L3 — agent → merchant (payment or checkout mandate, split into L3a / L3b\n * cross-referenced via transaction_id)\n *\n * This module does EXTRACTION ONLY — it decodes SD-JWT structure and pulls\n * out the mandate type, kid, executionMode, 8 constraint types, checkoutHash\n * (constraint type 8), transactionId, and raw layers for later verification.\n *\n * Signature verification lives in vi-verify.ts; this module uses @sd-jwt's\n * sync decoder with a SHA-256 hasher for structural parsing only.\n */\n\nimport { splitSdJwt, decodeSdJwtSync } from '@sd-jwt/decode';\nimport { createHash } from 'node:crypto';\nimport type { VIMandateType } from './purpose-mapping';\n\nexport type { VIMandateType };\nexport type VIExecutionMode = 'Immediate' | 'Autonomous' | 'Both';\n\nexport interface VIAllowedParty {\n id?: string;\n name?: string;\n website?: string;\n}\n\nexport interface VILineItem {\n id?: string;\n acceptableItems?: string[];\n quantity?: number;\n}\n\nexport interface VIPaymentAmount {\n currency?: string;\n min?: number;\n max?: number;\n}\n\nexport interface VIBudgetLimit {\n currency?: string;\n max?: number;\n}\n\nexport interface VIRecurrence {\n frequency?: string;\n startDate?: string;\n endDate?: string;\n maxOccurrences?: number;\n}\n\nexport interface VIConstraints {\n allowedMerchants?: VIAllowedParty[];\n allowedPayees?: VIAllowedParty[];\n lineItems?: VILineItem[];\n paymentAmount?: VIPaymentAmount;\n budgetLimit?: VIBudgetLimit;\n recurrence?: VIRecurrence;\n agentRecurrence?: VIRecurrence;\n}\n\nexport interface VIExtractedClaims {\n mandateType: VIMandateType;\n kid?: string;\n executionMode?: VIExecutionMode;\n credentialProvider?: string;\n constraints: VIConstraints;\n /** VI constraint type 8 — SHA-256 of the paired L2 checkout disclosure. */\n checkoutHash?: string;\n transactionId?: string;\n rawLayers: { l1?: string; l2?: string; l3?: string };\n}\n\n/**\n * Extract VI claims from a compact SD-JWT string.\n *\n * Input shape:\n * <jwt>~<disclosure1>~<disclosure2>~...~<kbJwt?>\n *\n * Returns null if parsing fails at any layer. Does not verify signatures.\n */\nexport function extractVIClaims(sdJwtCompact: string): VIExtractedClaims | null {\n if (!sdJwtCompact || typeof sdJwtCompact !== 'string') return null;\n\n let decoded;\n try {\n decoded = decodeSdJwtSync(sdJwtCompact, sha256Sync);\n } catch {\n return null;\n }\n\n const split = safeSplit(sdJwtCompact);\n\n const payload = (decoded.jwt?.payload ?? {}) as Record<string, unknown>;\n const disclosures = decoded.disclosures ?? [];\n\n // Apply disclosures onto payload to resolve _sd references.\n // Disclosure from @sd-jwt/utils has { key, value, digest() } where digest is\n // a function — we only need key+value here, so narrow via a structural cast.\n const claims = applyDisclosures(\n payload,\n disclosures as unknown as Array<{ key?: string; value?: unknown }>\n );\n\n const mandateType = coerceMandateType(\n claims.mandate_type ?? claims.mandateType ?? payload.mandate_type ?? payload.mandateType\n );\n if (!mandateType) return null;\n\n const kid = coerceString(\n (decoded.jwt?.header as Record<string, unknown> | undefined)?.kid ?? claims.kid ?? payload.kid\n );\n\n const executionMode = coerceExecutionMode(claims.execution_mode ?? claims.executionMode);\n const credentialProvider = coerceString(claims.iss ?? payload.iss);\n\n const constraints = extractConstraints(\n (claims.constraints ?? claims.default_constraints ?? {}) as Record<string, unknown>\n );\n\n const transactionId = coerceString(claims.transaction_id ?? claims.transactionId);\n const checkoutHash = coerceString(\n claims.checkout_hash ??\n claims.conditional_transaction_id ??\n (claims.payment_reference as Record<string, unknown> | undefined)?.checkout_hash\n );\n\n return {\n mandateType,\n kid,\n executionMode,\n credentialProvider,\n constraints,\n checkoutHash,\n transactionId,\n rawLayers: split,\n };\n}\n\nfunction safeSplit(compact: string): { l1?: string; l2?: string; l3?: string } {\n try {\n const { jwt, kbJwt } = splitSdJwt(compact);\n // VI layering maps loosely: the outer JWT is L3 (agent mandate), KB-JWT\n // (if present) is the key-binding proof, and disclosures carry L2/L1 fragments.\n return { l3: jwt, l2: kbJwt };\n } catch {\n return {};\n }\n}\n\nfunction applyDisclosures(\n payload: Record<string, unknown>,\n disclosures: Array<{ key?: string; value?: unknown }>\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...payload };\n for (const d of disclosures) {\n if (d.key && d.value !== undefined && !(d.key in result)) {\n result[d.key] = d.value;\n }\n }\n return result;\n}\n\nfunction extractConstraints(raw: Record<string, unknown>): VIConstraints {\n return {\n allowedMerchants: toAllowedPartyArray(raw.allowed_merchants ?? raw.allowedMerchants),\n allowedPayees: toAllowedPartyArray(raw.allowed_payees ?? raw.allowedPayees),\n lineItems: toLineItemArray(raw.line_items ?? raw.lineItems),\n paymentAmount: toPaymentAmount(raw.payment_amount ?? raw.paymentAmount),\n budgetLimit: toBudgetLimit(raw.budget_limit ?? raw.budgetLimit ?? raw.budget),\n recurrence: toRecurrence(raw.recurrence),\n agentRecurrence: toRecurrence(raw.agent_recurrence ?? raw.agentRecurrence),\n };\n}\n\nfunction toAllowedPartyArray(v: unknown): VIAllowedParty[] | undefined {\n if (!Array.isArray(v)) return undefined;\n const out: VIAllowedParty[] = [];\n for (const item of v) {\n if (item && typeof item === 'object') {\n const r = item as Record<string, unknown>;\n out.push({\n id: coerceString(r.id),\n name: coerceString(r.name),\n website: coerceString(r.website),\n });\n }\n }\n return out.length > 0 ? out : undefined;\n}\n\nfunction toLineItemArray(v: unknown): VILineItem[] | undefined {\n if (!Array.isArray(v)) return undefined;\n const out: VILineItem[] = [];\n for (const item of v) {\n if (item && typeof item === 'object') {\n const r = item as Record<string, unknown>;\n const acc = r.acceptable_items ?? r.acceptableItems;\n out.push({\n id: coerceString(r.id),\n acceptableItems: Array.isArray(acc)\n ? (acc.filter((a) => typeof a === 'string') as string[])\n : undefined,\n quantity: coerceNumber(r.quantity),\n });\n }\n }\n return out.length > 0 ? out : undefined;\n}\n\nfunction toPaymentAmount(v: unknown): VIPaymentAmount | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const r = v as Record<string, unknown>;\n return {\n currency: coerceString(r.currency),\n min: coerceNumber(r.min),\n max: coerceNumber(r.max),\n };\n}\n\nfunction toBudgetLimit(v: unknown): VIBudgetLimit | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const r = v as Record<string, unknown>;\n return {\n currency: coerceString(r.currency),\n max: coerceNumber(r.max),\n };\n}\n\nfunction toRecurrence(v: unknown): VIRecurrence | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const r = v as Record<string, unknown>;\n return {\n frequency: coerceString(r.frequency),\n startDate: coerceString(r.start_date ?? r.startDate),\n endDate: coerceString(r.end_date ?? r.endDate),\n maxOccurrences: coerceNumber(r.max_occurrences ?? r.maxOccurrences),\n };\n}\n\nfunction coerceMandateType(v: unknown): VIMandateType | null {\n if (v === 'checkout' || v === 'payment' || v === 'checkout.open' || v === 'payment.open') {\n return v;\n }\n return null;\n}\n\nfunction coerceExecutionMode(v: unknown): VIExecutionMode | undefined {\n return v === 'Immediate' || v === 'Autonomous' || v === 'Both' ? v : undefined;\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n\nfunction coerceNumber(v: unknown): number | undefined {\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (typeof v === 'string') {\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n }\n return undefined;\n}\n\nfunction sha256Sync(data: string | ArrayBuffer): Uint8Array {\n const buf =\n typeof data === 'string' ? Buffer.from(data, 'utf-8') : Buffer.from(new Uint8Array(data));\n const hash = createHash('sha256').update(buf).digest();\n return new Uint8Array(hash.buffer, hash.byteOffset, hash.byteLength);\n}\n","/**\n * Stripe webhook HMAC-SHA256 verifier (inline).\n *\n * Stripe-Signature header format: \"t=TIMESTAMP,v1=HEX_SIGNATURE\"\n * - t: unix seconds when Stripe signed the webhook\n * - v1: HMAC-SHA256(webhook_secret, `${t}.${payload}`) as hex\n *\n * Multiple v1 signatures can coexist during secret rotation; any match wins.\n * Default tolerance on timestamp age: 300s (matches Stripe's own default).\n *\n * Documented at docs.stripe.com — we intentionally inline ~25 LOC rather\n * than pull in the full stripe npm package (MIT but 600KB+ with deps).\n */\n\nimport { createHmac, timingSafeEqual } from 'node:crypto';\n\nexport interface VerifyStripeWebhookResult {\n ok: boolean;\n timestamp?: number;\n error?: string;\n}\n\nexport interface VerifyStripeWebhookOptions {\n toleranceSec?: number;\n /** Injectable for deterministic tests. */\n now?: () => number;\n}\n\nexport function verifyStripeWebhook(\n payload: string,\n signatureHeader: string | undefined,\n secret: string,\n options: VerifyStripeWebhookOptions = {}\n): VerifyStripeWebhookResult {\n if (!signatureHeader) return { ok: false, error: 'missing Stripe-Signature header' };\n if (!secret) return { ok: false, error: 'missing webhook secret' };\n\n const parsed = parseStripeSignature(signatureHeader);\n if (!parsed.timestamp) return { ok: false, error: 'malformed Stripe-Signature (missing t=)' };\n if (parsed.v1Signatures.length === 0) {\n return { ok: false, error: 'malformed Stripe-Signature (no v1=)' };\n }\n\n const tolerance = options.toleranceSec ?? 300;\n const now = options.now ? options.now() : Math.floor(Date.now() / 1000);\n if (Math.abs(now - parsed.timestamp) > tolerance) {\n return {\n ok: false,\n timestamp: parsed.timestamp,\n error: `timestamp outside tolerance (${tolerance}s)`,\n };\n }\n\n const signedPayload = `${parsed.timestamp}.${payload}`;\n const expected = createHmac('sha256', secret).update(signedPayload).digest();\n\n for (const candidateHex of parsed.v1Signatures) {\n const candidate = hexToBuffer(candidateHex);\n if (!candidate) continue;\n if (candidate.length !== expected.length) continue;\n if (timingSafeEqual(candidate, expected)) {\n return { ok: true, timestamp: parsed.timestamp };\n }\n }\n\n return { ok: false, timestamp: parsed.timestamp, error: 'signature mismatch' };\n}\n\ninterface ParsedStripeSignature {\n timestamp: number | null;\n v1Signatures: string[];\n}\n\nfunction parseStripeSignature(header: string): ParsedStripeSignature {\n let timestamp: number | null = null;\n const v1Signatures: string[] = [];\n for (const part of header.split(',')) {\n const [rawKey, rawValue] = part.split('=');\n if (!rawKey || !rawValue) continue;\n const key = rawKey.trim();\n const value = rawValue.trim();\n if (key === 't') {\n const n = Number(value);\n if (Number.isFinite(n)) timestamp = n;\n } else if (key === 'v1') {\n v1Signatures.push(value);\n }\n }\n return { timestamp, v1Signatures };\n}\n\nfunction hexToBuffer(hex: string): Buffer | null {\n if (!/^[0-9a-fA-F]+$/.test(hex) || hex.length % 2 !== 0) return null;\n return Buffer.from(hex, 'hex');\n}\n","/**\n * PDLSS constraint evaluation.\n *\n * Evaluates VI constraint types 1-4 (merchant/payee allowlists, line items,\n * payment amount) + MPP/x402 payment-method allowlist + spending-limit\n * against a transaction context.\n *\n * Types 5/6/7 (budget, recurrence, agent_recurrence) extract through but\n * enforcement is deferred to the cross-merchant budget service (§3.3.15,\n * separate PR). This module returns per-constraint {ok, reason} results\n * so a policy layer can decide hard-deny vs trust-signal.\n */\n\nimport type { VIConstraints, VIAllowedParty, VILineItem, VIPaymentAmount } from './vi';\n\nexport interface TransactionContext {\n amount?: number;\n currency?: string;\n merchant?: { id?: string; website?: string };\n payee?: { id?: string; website?: string };\n lineItems?: Array<{ id?: string; quantity?: number }>;\n /** For MPP / x402 payment-method enforcement. */\n paymentMethod?: string;\n}\n\nexport type ConstraintKey = 'merchant' | 'payee' | 'lineItems' | 'amount' | 'paymentMethod';\n\nexport interface ConstraintResult {\n ok: boolean;\n reason?: string;\n}\n\nexport interface ConstraintEvalResult {\n ok: boolean;\n results: Record<string, ConstraintResult>;\n reasons: string[];\n}\n\nexport interface VIConstraintEvalInput {\n constraints: VIConstraints;\n transaction: TransactionContext;\n}\n\nexport function evaluateVIConstraints(input: VIConstraintEvalInput): ConstraintEvalResult {\n const { constraints, transaction } = input;\n const results: Record<string, ConstraintResult> = {};\n\n if (constraints.allowedMerchants && constraints.allowedMerchants.length > 0) {\n results.merchant = evaluateAllowlist(\n 'merchant',\n constraints.allowedMerchants,\n transaction.merchant\n );\n }\n\n if (constraints.allowedPayees && constraints.allowedPayees.length > 0) {\n results.payee = evaluateAllowlist('payee', constraints.allowedPayees, transaction.payee);\n }\n\n if (constraints.lineItems && constraints.lineItems.length > 0) {\n results.lineItems = evaluateLineItems(constraints.lineItems, transaction.lineItems ?? []);\n }\n\n if (constraints.paymentAmount) {\n results.amount = evaluatePaymentAmount(constraints.paymentAmount, transaction);\n }\n\n const reasons: string[] = [];\n let ok = true;\n for (const [key, r] of Object.entries(results)) {\n if (!r.ok) {\n ok = false;\n reasons.push(r.reason ?? `${key} failed`);\n }\n }\n\n return { ok, results, reasons };\n}\n\nexport interface PaymentMethodAllowlistInput {\n allowedMethods?: string[];\n requestedMethod?: string;\n}\n\nexport function evaluatePaymentMethodAllowlist(\n input: PaymentMethodAllowlistInput\n): ConstraintResult {\n const allow = input.allowedMethods ?? [];\n if (allow.length === 0) return { ok: true };\n if (!input.requestedMethod) {\n return { ok: false, reason: 'no payment method in request; allowlist configured' };\n }\n const lowered = input.requestedMethod.toLowerCase();\n const allowed = allow.some((m) => m.toLowerCase() === lowered);\n if (!allowed) {\n return {\n ok: false,\n reason: `payment method \"${input.requestedMethod}\" not in allowlist [${allow.join(', ')}]`,\n };\n }\n return { ok: true };\n}\n\nexport interface SpendingLimitInput {\n limit?: { amount?: number; currency?: string };\n requested?: { amount?: number; currency?: string };\n}\n\nexport function evaluateSpendingLimit(input: SpendingLimitInput): ConstraintResult {\n const { limit, requested } = input;\n if (!limit || typeof limit.amount !== 'number') return { ok: true };\n if (!requested || typeof requested.amount !== 'number') return { ok: true };\n if (limit.currency && requested.currency && limit.currency !== requested.currency) {\n return {\n ok: false,\n reason: `currency mismatch: limit ${limit.currency} vs requested ${requested.currency}`,\n };\n }\n if (requested.amount > limit.amount) {\n return {\n ok: false,\n reason:\n `requested ${requested.amount} ${requested.currency ?? ''} exceeds limit ${limit.amount} ${limit.currency ?? ''}`.trim(),\n };\n }\n return { ok: true };\n}\n\nfunction evaluateAllowlist(\n kind: 'merchant' | 'payee',\n allowlist: VIAllowedParty[],\n actual: { id?: string; website?: string } | undefined\n): ConstraintResult {\n if (!actual || (!actual.id && !actual.website)) {\n return { ok: false, reason: `no ${kind} in transaction; allowlist configured` };\n }\n for (const entry of allowlist) {\n if (entry.id && actual.id && entry.id === actual.id) return { ok: true };\n if (entry.website && actual.website && domainsMatch(entry.website, actual.website)) {\n return { ok: true };\n }\n }\n const allowedDescriptors = allowlist.map(describeParty).join(', ');\n const actualDescriptor = describeParty(actual);\n return {\n ok: false,\n reason: `${kind} ${actualDescriptor} not in allowlist [${allowedDescriptors}]`,\n };\n}\n\nfunction evaluateLineItems(\n allowlist: VILineItem[],\n actualItems: Array<{ id?: string; quantity?: number }>\n): ConstraintResult {\n if (actualItems.length === 0) {\n return { ok: false, reason: 'no line items in transaction; allowlist configured' };\n }\n const reasons: string[] = [];\n for (const item of actualItems) {\n const match = allowlist.find(\n (a) => (a.id && a.id === item.id) || (a.acceptableItems ?? []).includes(item.id ?? '')\n );\n if (!match) {\n reasons.push(`line item \"${item.id ?? '(unnamed)'}\" not in allowlist`);\n continue;\n }\n if (\n typeof match.quantity === 'number' &&\n typeof item.quantity === 'number' &&\n item.quantity > match.quantity\n ) {\n reasons.push(\n `line item \"${item.id}\" quantity ${item.quantity} exceeds allowed ${match.quantity}`\n );\n }\n }\n return reasons.length === 0 ? { ok: true } : { ok: false, reason: reasons.join('; ') };\n}\n\nfunction evaluatePaymentAmount(\n bound: VIPaymentAmount,\n transaction: TransactionContext\n): ConstraintResult {\n if (typeof transaction.amount !== 'number') {\n return { ok: false, reason: 'no amount in transaction; paymentAmount bound configured' };\n }\n if (bound.currency && transaction.currency && bound.currency !== transaction.currency) {\n return {\n ok: false,\n reason: `currency mismatch: bound ${bound.currency} vs transaction ${transaction.currency}`,\n };\n }\n if (typeof bound.min === 'number' && transaction.amount < bound.min) {\n return {\n ok: false,\n reason: `amount ${transaction.amount} below min ${bound.min}`,\n };\n }\n if (typeof bound.max === 'number' && transaction.amount > bound.max) {\n return {\n ok: false,\n reason: `amount ${transaction.amount} above max ${bound.max}`,\n };\n }\n return { ok: true };\n}\n\nfunction domainsMatch(allow: string, actual: string): boolean {\n const a = normalizeDomain(allow);\n const b = normalizeDomain(actual);\n return a === b || b.endsWith(`.${a}`);\n}\n\nfunction normalizeDomain(value: string): string {\n try {\n const withScheme = /^https?:\\/\\//.test(value) ? value : `https://${value}`;\n return new URL(withScheme).hostname.toLowerCase();\n } catch {\n return value.toLowerCase();\n }\n}\n\nfunction describeParty(party: { id?: string; name?: string; website?: string }): string {\n if (party.id) return `id:${party.id}`;\n if (party.website) return party.website;\n if (party.name) return party.name;\n return '(unnamed)';\n}\n","/**\n * Cross-protocol agent identity binding.\n *\n * Every commerce layer claims an agent identity differently:\n * - VI L3 kid (SD-JWT header)\n * - AP2 agent_id (mandate payload)\n * - ACP Authorization: Bearer token (merchant-issued pre-shared)\n * - MPP Credential `source` field (DID or chain-native key)\n * - x402 client wallet address\n * - RFC 9421 kid (Agent Pay / TAP / Web Bot Auth)\n *\n * This module maps any such claim to a single AstraSync agent via a\n * caller-supplied resolver (typically delegates to the counterparty service),\n * then flags whether multiple claims on the same request resolve to different\n * agents (a trust signal for PDLSS).\n *\n * This is AstraSync whitespace — no vendor owns multi-protocol identity\n * unification.\n */\n\nexport interface IdentityClaim {\n /** Originating protocol label: 'vi' | 'ap2' | 'acp' | 'mpp' | 'x402' | 'agentpay' | 'tap' | 'webbotauth' */\n protocol: string;\n /** Claim field name, e.g. 'kid', 'agent_id', 'source', 'bearer'. */\n field: string;\n /** Claim value as presented on the wire. */\n value: string;\n}\n\nexport interface IdentityBindingResult {\n claims: IdentityClaim[];\n mappedAstraSyncAgentId?: string;\n /**\n * True when two or more claims resolve to different AstraSync agents.\n * Surfaced as a trust signal rather than an auto-deny — legitimate flows\n * (e.g. delegate payments) can legitimately carry multiple identities.\n */\n mismatchAcrossLayers: boolean;\n /** Per-claim resolution result for audit / debugging. */\n resolutions: Array<{ claim: IdentityClaim; agentId: string | null }>;\n}\n\nexport type IdentityResolver = (claim: IdentityClaim) => Promise<string | null>;\n\nexport async function bindIdentity(\n claims: IdentityClaim[],\n resolver: IdentityResolver\n): Promise<IdentityBindingResult> {\n const resolutions: Array<{ claim: IdentityClaim; agentId: string | null }> = [];\n for (const claim of claims) {\n if (!claim.value) {\n resolutions.push({ claim, agentId: null });\n continue;\n }\n const agentId = await resolver(claim);\n resolutions.push({ claim, agentId });\n }\n\n const resolvedIds = resolutions\n .map((r) => r.agentId)\n .filter((id): id is string => typeof id === 'string' && id.length > 0);\n\n const unique = Array.from(new Set(resolvedIds));\n const mismatchAcrossLayers = unique.length > 1;\n const mappedAstraSyncAgentId = unique.length === 1 ? unique[0] : undefined;\n\n return {\n claims,\n mappedAstraSyncAgentId,\n mismatchAcrossLayers,\n resolutions,\n };\n}\n\n/**\n * Helper constructors — keep protocol/field strings consistent across the\n * codebase and make tests readable.\n */\nexport const claim = {\n viKid: (value: string): IdentityClaim => ({ protocol: 'vi', field: 'kid', value }),\n ap2AgentId: (value: string): IdentityClaim => ({ protocol: 'ap2', field: 'agent_id', value }),\n acpBearer: (value: string): IdentityClaim => ({ protocol: 'acp', field: 'bearer', value }),\n mppSource: (value: string): IdentityClaim => ({ protocol: 'mpp', field: 'source', value }),\n x402Wallet: (value: string): IdentityClaim => ({ protocol: 'x402', field: 'wallet', value }),\n agentPayKid: (value: string): IdentityClaim => ({ protocol: 'agentpay', field: 'kid', value }),\n tapKid: (value: string): IdentityClaim => ({ protocol: 'tap', field: 'kid', value }),\n webBotAuthKid: (value: string): IdentityClaim => ({\n protocol: 'webbotauth',\n field: 'kid',\n value,\n }),\n};\n","/**\n * AP2 (Agent Payments Protocol) mandate extraction.\n *\n * Google-led, launched 3 April 2026 with 60+ partners (Mastercard, PayPal,\n * Coinbase, AmEx, Revolut, UnionPay, ...). AP2 ships three mandate types as\n * SD-JWTs in series:\n * - intent_mandate — user declares intent (amount, merchant category, etc.)\n * - cart_mandate — user approves a cart (specific items, totals)\n * - payment_mandate — authorizes the actual payment rail\n *\n * Mandates are cross-referenced via ids; each is an SD-JWT over ES256 (or\n * equivalent). We decode via @sd-jwt/decode and extract the AP2-specific\n * shape — verification lives in ap2-verify.ts.\n */\n\nimport { decodeSdJwtSync } from '@sd-jwt/decode';\nimport { createHash } from 'node:crypto';\nimport type { AP2MandateType } from './purpose-mapping';\n\nexport type { AP2MandateType };\n\nexport interface AP2PaymentDetailsTotal {\n amount?: { value?: string | number; currency?: string };\n label?: string;\n}\n\nexport interface AP2IntentMandateClaims {\n type: 'intent_mandate';\n agent_id?: string;\n user_id?: string;\n merchant_category?: string;\n allowedMerchantDomains?: string[];\n paymentMethods?: string[];\n expires?: string;\n payment_details_total?: AP2PaymentDetailsTotal;\n raw: Record<string, unknown>;\n}\n\nexport interface AP2CartMandateClaims {\n type: 'cart_mandate';\n agent_id?: string;\n intent_mandate_id?: string;\n merchant_id?: string;\n line_items?: Array<{\n id?: string;\n quantity?: number;\n price?: { value?: string | number; currency?: string };\n }>;\n payment_details_total?: AP2PaymentDetailsTotal;\n expires?: string;\n raw: Record<string, unknown>;\n}\n\nexport interface AP2PaymentMandateClaims {\n type: 'payment_mandate';\n agent_id?: string;\n cart_mandate_id?: string;\n payment_method?: string;\n payment_details_total?: AP2PaymentDetailsTotal;\n credential_provider?: string;\n raw: Record<string, unknown>;\n}\n\nexport type AP2MandateClaims =\n | AP2IntentMandateClaims\n | AP2CartMandateClaims\n | AP2PaymentMandateClaims;\n\nexport interface AP2MandateTriple {\n intent?: AP2IntentMandateClaims;\n cart?: AP2CartMandateClaims;\n payment?: AP2PaymentMandateClaims;\n rawLayers: { intentJwt?: string; cartJwt?: string; paymentJwt?: string };\n}\n\n/**\n * Extract a single AP2 mandate from a compact SD-JWT.\n * Returns null if the SD-JWT is malformed or lacks a recognized type field.\n */\nexport function extractAP2Mandate(sdJwtCompact: string): AP2MandateClaims | null {\n if (!sdJwtCompact || typeof sdJwtCompact !== 'string') return null;\n\n let decoded;\n try {\n decoded = decodeSdJwtSync(sdJwtCompact, sha256Sync);\n } catch {\n return null;\n }\n\n const payload = (decoded.jwt?.payload ?? {}) as Record<string, unknown>;\n const disclosures = decoded.disclosures ?? [];\n const claims = applyDisclosures(\n payload,\n disclosures as unknown as Array<{ key?: string; value?: unknown }>\n );\n\n const type = coerceMandateType(claims.type ?? claims.mandate_type ?? claims.mandateType);\n if (!type) return null;\n\n if (type === 'intent_mandate') return buildIntent(claims);\n if (type === 'cart_mandate') return buildCart(claims);\n return buildPayment(claims);\n}\n\nexport interface AP2MandateTripleInput {\n intent?: string;\n cart?: string;\n payment?: string;\n}\n\n/**\n * Extract an intent / cart / payment triple, returning whichever are present.\n * Does NOT enforce cross-reference consistency — that's ap2-verify.ts's job.\n */\nexport function extractAP2Mandates(input: AP2MandateTripleInput): AP2MandateTriple {\n const intent = input.intent\n ? (extractAP2Mandate(input.intent) as AP2IntentMandateClaims | null)\n : null;\n const cart = input.cart ? (extractAP2Mandate(input.cart) as AP2CartMandateClaims | null) : null;\n const payment = input.payment\n ? (extractAP2Mandate(input.payment) as AP2PaymentMandateClaims | null)\n : null;\n return {\n intent: intent ?? undefined,\n cart: cart ?? undefined,\n payment: payment ?? undefined,\n rawLayers: {\n intentJwt: input.intent,\n cartJwt: input.cart,\n paymentJwt: input.payment,\n },\n };\n}\n\nfunction buildIntent(claims: Record<string, unknown>): AP2IntentMandateClaims {\n return {\n type: 'intent_mandate',\n agent_id: coerceString(claims.agent_id ?? claims.agentId),\n user_id: coerceString(claims.user_id ?? claims.userId ?? claims.sub),\n merchant_category: coerceString(claims.merchant_category ?? claims.merchantCategory),\n allowedMerchantDomains: toStringArray(\n claims.allowed_merchant_domains ?? claims.allowedMerchantDomains\n ),\n paymentMethods: toStringArray(claims.payment_methods ?? claims.paymentMethods),\n expires: coerceString(claims.expires ?? claims.exp),\n payment_details_total: toPaymentDetails(claims.payment_details_total ?? claims.total),\n raw: claims,\n };\n}\n\nfunction buildCart(claims: Record<string, unknown>): AP2CartMandateClaims {\n return {\n type: 'cart_mandate',\n agent_id: coerceString(claims.agent_id ?? claims.agentId),\n intent_mandate_id: coerceString(claims.intent_mandate_id ?? claims.intentMandateId),\n merchant_id: coerceString(claims.merchant_id ?? claims.merchantId),\n line_items: toLineItems(claims.line_items ?? claims.lineItems),\n payment_details_total: toPaymentDetails(claims.payment_details_total ?? claims.total),\n expires: coerceString(claims.expires ?? claims.exp),\n raw: claims,\n };\n}\n\nfunction buildPayment(claims: Record<string, unknown>): AP2PaymentMandateClaims {\n return {\n type: 'payment_mandate',\n agent_id: coerceString(claims.agent_id ?? claims.agentId),\n cart_mandate_id: coerceString(claims.cart_mandate_id ?? claims.cartMandateId),\n payment_method: coerceString(claims.payment_method ?? claims.paymentMethod),\n payment_details_total: toPaymentDetails(claims.payment_details_total ?? claims.total),\n credential_provider: coerceString(claims.credential_provider ?? claims.credentialProvider),\n raw: claims,\n };\n}\n\nfunction toPaymentDetails(v: unknown): AP2PaymentDetailsTotal | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const r = v as Record<string, unknown>;\n const amount = r.amount as Record<string, unknown> | undefined;\n return {\n amount: amount\n ? {\n value: coerceStringOrNumber(amount.value),\n currency: coerceString(amount.currency),\n }\n : undefined,\n label: coerceString(r.label),\n };\n}\n\nfunction toLineItems(v: unknown): AP2CartMandateClaims['line_items'] {\n if (!Array.isArray(v)) return undefined;\n const items: NonNullable<AP2CartMandateClaims['line_items']> = [];\n for (const item of v) {\n if (!item || typeof item !== 'object') continue;\n const r = item as Record<string, unknown>;\n const price = r.price as Record<string, unknown> | undefined;\n items.push({\n id: coerceString(r.id),\n quantity: coerceNumber(r.quantity),\n price: price\n ? {\n value: coerceStringOrNumber(price.value),\n currency: coerceString(price.currency),\n }\n : undefined,\n });\n }\n return items.length > 0 ? items : undefined;\n}\n\nfunction toStringArray(v: unknown): string[] | undefined {\n if (!Array.isArray(v)) return undefined;\n const out = v.filter((i): i is string => typeof i === 'string' && i.length > 0);\n return out.length > 0 ? out : undefined;\n}\n\nfunction applyDisclosures(\n payload: Record<string, unknown>,\n disclosures: Array<{ key?: string; value?: unknown }>\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...payload };\n for (const d of disclosures) {\n if (d.key && d.value !== undefined && !(d.key in result)) {\n result[d.key] = d.value;\n }\n }\n return result;\n}\n\nfunction coerceMandateType(v: unknown): AP2MandateType | null {\n if (v === 'intent_mandate' || v === 'cart_mandate' || v === 'payment_mandate') return v;\n return null;\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n\nfunction coerceNumber(v: unknown): number | undefined {\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (typeof v === 'string') {\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n }\n return undefined;\n}\n\nfunction coerceStringOrNumber(v: unknown): string | number | undefined {\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (typeof v === 'string' && v.length > 0) return v;\n return undefined;\n}\n\nfunction sha256Sync(data: string | ArrayBuffer): Uint8Array {\n const buf =\n typeof data === 'string' ? Buffer.from(data, 'utf-8') : Buffer.from(new Uint8Array(data));\n const hash = createHash('sha256').update(buf).digest();\n return new Uint8Array(hash.buffer, hash.byteOffset, hash.byteLength);\n}\n","/**\n * AP2 mandate chain verification.\n *\n * Checks the cross-reference consistency of an intent → cart → payment\n * triple. Does NOT verify cryptographic signatures here (that's a call to\n * @sd-jwt/core which needs the agent's / CP's public key; expose via a\n * verifier callback so pipeline can plug in the right resolver).\n *\n * Rules (per AP2 spec v0.1-draft):\n * - cart.intent_mandate_id must equal the intent mandate's canonical id (if present)\n * - payment.cart_mandate_id must equal the cart mandate's canonical id (if present)\n * - agent_id must match across all three layers\n * - payment_method in payment mandate must be in intent.paymentMethods (if declared)\n * - cart totals must not exceed intent totals (if both declared in same currency)\n * - no mandate may be expired (beyond clock skew)\n */\n\nimport type { AP2MandateTriple } from './ap2';\n\nexport interface AP2VerifyInput {\n triple: AP2MandateTriple;\n clockSkewSec?: number;\n now?: () => number;\n}\n\nexport interface AP2ChainResult {\n ok: boolean;\n checks: {\n intentPresent: boolean;\n cartRefOk: boolean;\n paymentRefOk: boolean;\n agentIdContinuity: boolean;\n paymentMethodAllowed: boolean;\n totalsConsistent: boolean;\n expiryOk: boolean;\n };\n agentId?: string;\n errors: string[];\n}\n\nexport function verifyAP2Chain(input: AP2VerifyInput): AP2ChainResult {\n const { triple } = input;\n const errors: string[] = [];\n\n const intentPresent = triple.intent !== undefined;\n const cartRefOk = checkCartRef(triple, errors);\n const paymentRefOk = checkPaymentRef(triple, errors);\n const { ok: agentIdContinuity, agentId } = checkAgentContinuity(triple, errors);\n const paymentMethodAllowed = checkPaymentMethod(triple, errors);\n const totalsConsistent = checkTotals(triple, errors);\n const expiryOk = checkExpiries(triple, input.clockSkewSec ?? 300, input.now, errors);\n\n const ok =\n cartRefOk &&\n paymentRefOk &&\n agentIdContinuity &&\n paymentMethodAllowed &&\n totalsConsistent &&\n expiryOk;\n\n return {\n ok,\n checks: {\n intentPresent,\n cartRefOk,\n paymentRefOk,\n agentIdContinuity,\n paymentMethodAllowed,\n totalsConsistent,\n expiryOk,\n },\n agentId,\n errors,\n };\n}\n\nfunction checkCartRef(triple: AP2MandateTriple, errors: string[]): boolean {\n const cart = triple.cart;\n if (!cart) return true;\n if (!cart.intent_mandate_id) return true;\n const intentId = triple.intent?.raw?.id as string | undefined;\n if (intentId && cart.intent_mandate_id !== intentId) {\n errors.push(\n `cart.intent_mandate_id (${cart.intent_mandate_id}) does not match intent.id (${intentId})`\n );\n return false;\n }\n return true;\n}\n\nfunction checkPaymentRef(triple: AP2MandateTriple, errors: string[]): boolean {\n const payment = triple.payment;\n if (!payment) return true;\n if (!payment.cart_mandate_id) return true;\n const cartId = triple.cart?.raw?.id as string | undefined;\n if (cartId && payment.cart_mandate_id !== cartId) {\n errors.push(\n `payment.cart_mandate_id (${payment.cart_mandate_id}) does not match cart.id (${cartId})`\n );\n return false;\n }\n return true;\n}\n\nfunction checkAgentContinuity(\n triple: AP2MandateTriple,\n errors: string[]\n): { ok: boolean; agentId?: string } {\n const ids = [triple.intent?.agent_id, triple.cart?.agent_id, triple.payment?.agent_id].filter(\n (id): id is string => typeof id === 'string' && id.length > 0\n );\n if (ids.length === 0) return { ok: true };\n const unique = new Set(ids);\n if (unique.size > 1) {\n errors.push(`agent_id mismatch across mandates: ${Array.from(unique).join(', ')}`);\n return { ok: false, agentId: undefined };\n }\n return { ok: true, agentId: ids[0] };\n}\n\nfunction checkPaymentMethod(triple: AP2MandateTriple, errors: string[]): boolean {\n const paymentMethod = triple.payment?.payment_method;\n const allowed = triple.intent?.paymentMethods;\n if (!paymentMethod || !allowed || allowed.length === 0) return true;\n if (!allowed.includes(paymentMethod)) {\n errors.push(\n `payment_method \"${paymentMethod}\" not in intent.paymentMethods [${allowed.join(', ')}]`\n );\n return false;\n }\n return true;\n}\n\nfunction checkTotals(triple: AP2MandateTriple, errors: string[]): boolean {\n const intentTotal = toNumericAmount(triple.intent?.payment_details_total);\n const cartTotal = toNumericAmount(triple.cart?.payment_details_total);\n const paymentTotal = toNumericAmount(triple.payment?.payment_details_total);\n\n if (intentTotal && cartTotal && intentTotal.currency === cartTotal.currency) {\n if (cartTotal.value > intentTotal.value) {\n errors.push(\n `cart total ${cartTotal.value} ${cartTotal.currency} exceeds intent cap ${intentTotal.value}`\n );\n return false;\n }\n }\n if (cartTotal && paymentTotal && cartTotal.currency === paymentTotal.currency) {\n if (paymentTotal.value > cartTotal.value) {\n errors.push(\n `payment total ${paymentTotal.value} ${paymentTotal.currency} exceeds cart total ${cartTotal.value}`\n );\n return false;\n }\n }\n return true;\n}\n\nfunction checkExpiries(\n triple: AP2MandateTriple,\n toleranceSec: number,\n nowFn: (() => number) | undefined,\n errors: string[]\n): boolean {\n const now = nowFn ? nowFn() : Math.floor(Date.now() / 1000);\n let ok = true;\n for (const [name, mandate] of [\n ['intent', triple.intent],\n ['cart', triple.cart],\n ] as const) {\n if (!mandate?.expires) continue;\n const parsed = parseExpiry(mandate.expires);\n if (parsed === null) {\n errors.push(`${name}.expires unparseable`);\n ok = false;\n continue;\n }\n if (now > parsed + toleranceSec) {\n errors.push(`${name} mandate expired at ${mandate.expires}`);\n ok = false;\n }\n }\n return ok;\n}\n\nfunction toNumericAmount(\n total: import('./ap2').AP2PaymentDetailsTotal | undefined\n): { value: number; currency: string } | null {\n if (!total?.amount?.value || !total.amount.currency) return null;\n const n =\n typeof total.amount.value === 'string' ? Number(total.amount.value) : total.amount.value;\n if (!Number.isFinite(n)) return null;\n return { value: n, currency: total.amount.currency };\n}\n\nfunction parseExpiry(value: string): number | null {\n const asInt = Number(value);\n if (Number.isFinite(asInt) && asInt > 0) {\n return asInt >= 1e12 ? Math.floor(asInt / 1000) : Math.floor(asInt);\n }\n const parsedDate = Date.parse(value);\n if (Number.isFinite(parsedDate)) return Math.floor(parsedDate / 1000);\n return null;\n}\n","/**\n * ACP detached-JSON-signature verifier.\n *\n * ACP (Agentic Commerce Protocol, OpenAI + Stripe) uses detached JSON\n * signatures over request bodies. The public signature algorithm is NOT\n * specified in open docs as of April 2026 (docs.stripe.com/agentic-commerce/*\n * is Private Preview). We implement Ed25519 and ES256 candidates against\n * whichever public key the caller supplies, and report algorithm-unsupported\n * as a trust signal rather than a hard fail so policy can weight it.\n *\n * Timestamp freshness (>300s default) IS a hard fail — prevents replay.\n *\n * Bearer-token → AstraSync agent binding is delegated to caller-supplied\n * resolver (typically the counterparty service).\n */\n\nimport type { JWK } from 'jose';\n\nexport type ACPSignatureAlgorithm = 'ed25519' | 'es256' | 'unsupported';\n\nexport interface ACPVerifyInput {\n /** Raw request body over which the signature was computed. */\n rawBody: string;\n /** Value of the Signature header. Expected to be base64 (either standard or url). */\n signatureHeader?: string;\n /** Value of the Timestamp header (unix seconds as string, or ISO 8601). */\n timestampHeader?: string;\n /** Candidate public keys to try. First matching algorithm wins. */\n candidateKeys: Array<{ jwk: JWK; alg?: ACPSignatureAlgorithm | string }>;\n /** Clock skew tolerance in seconds (default 300). */\n clockSkewSec?: number;\n /** Injectable now for tests. */\n now?: () => number;\n}\n\nexport interface ACPVerifyResult {\n ok: boolean;\n algorithm?: ACPSignatureAlgorithm;\n error?: string;\n /** True when timestamp is outside tolerance. */\n timestampStale?: boolean;\n}\n\nexport async function verifyACPSignature(input: ACPVerifyInput): Promise<ACPVerifyResult> {\n if (!input.signatureHeader) {\n return { ok: false, error: 'missing Signature header' };\n }\n\n const freshness = checkTimestamp(input.timestampHeader, input.clockSkewSec ?? 300, input.now);\n if (!freshness.ok) {\n return { ok: false, error: freshness.error, timestampStale: true };\n }\n\n const signatureBytes = decodeBase64(input.signatureHeader);\n if (!signatureBytes) {\n return { ok: false, error: 'signature header is not valid base64' };\n }\n\n const bodyBytes = new TextEncoder().encode(input.rawBody);\n const { subtle } = await getSubtle();\n\n for (const candidate of input.candidateKeys) {\n const declaredAlg = normalizeAlgorithm(candidate.alg);\n const algsToTry: ACPSignatureAlgorithm[] =\n declaredAlg && declaredAlg !== 'unsupported' ? [declaredAlg] : ['ed25519', 'es256'];\n\n for (const alg of algsToTry) {\n try {\n const verified = await tryVerify(subtle, candidate.jwk, signatureBytes, bodyBytes, alg);\n if (verified) return { ok: true, algorithm: alg };\n } catch {\n // swallow per-candidate errors; try next algorithm/candidate\n }\n }\n }\n\n return {\n ok: false,\n algorithm: 'unsupported',\n error: 'no candidate key verified the signature under Ed25519 or ES256',\n };\n}\n\nasync function tryVerify(\n subtle: SubtleCrypto,\n jwk: JWK,\n signature: Uint8Array,\n body: Uint8Array,\n alg: ACPSignatureAlgorithm\n): Promise<boolean> {\n if (alg === 'ed25519') {\n if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') return false;\n const key = await subtle.importKey('jwk', jwk as JsonWebKey, { name: 'Ed25519' }, false, [\n 'verify',\n ]);\n return await subtle.verify({ name: 'Ed25519' }, key, toBuf(signature), toBuf(body));\n }\n if (alg === 'es256') {\n if (jwk.kty !== 'EC' || jwk.crv !== 'P-256') return false;\n const key = await subtle.importKey(\n 'jwk',\n jwk as JsonWebKey,\n { name: 'ECDSA', namedCurve: 'P-256' },\n false,\n ['verify']\n );\n return await subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n key,\n toBuf(signature),\n toBuf(body)\n );\n }\n return false;\n}\n\nfunction toBuf(bytes: Uint8Array): ArrayBuffer {\n const out = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(out).set(bytes);\n return out;\n}\n\nfunction checkTimestamp(\n headerValue: string | undefined,\n toleranceSec: number,\n nowFn?: () => number\n): { ok: true } | { ok: false; error: string } {\n if (!headerValue) return { ok: false, error: 'missing Timestamp header' };\n const ts = parseTimestamp(headerValue);\n if (ts === null) return { ok: false, error: 'unparseable Timestamp header' };\n const now = nowFn ? nowFn() : Math.floor(Date.now() / 1000);\n if (Math.abs(now - ts) > toleranceSec) {\n return { ok: false, error: `timestamp outside ${toleranceSec}s tolerance` };\n }\n return { ok: true };\n}\n\nfunction parseTimestamp(value: string): number | null {\n const asInt = Number(value);\n if (Number.isFinite(asInt) && asInt > 0) {\n // Treat >= 1e12 as milliseconds; otherwise seconds.\n return asInt >= 1e12 ? Math.floor(asInt / 1000) : Math.floor(asInt);\n }\n const parsedDate = Date.parse(value);\n if (Number.isFinite(parsedDate)) return Math.floor(parsedDate / 1000);\n return null;\n}\n\nfunction normalizeAlgorithm(alg: string | undefined): ACPSignatureAlgorithm | undefined {\n if (!alg) return undefined;\n const lowered = alg.toLowerCase();\n if (lowered === 'ed25519' || lowered === 'eddsa') return 'ed25519';\n if (lowered === 'es256' || lowered.startsWith('ecdsa-p256')) return 'es256';\n return 'unsupported';\n}\n\nfunction decodeBase64(value: string): Uint8Array | null {\n try {\n // Accept either standard base64 or url-safe; jose and node both accept both via Buffer.\n const normalized = value.replace(/-/g, '+').replace(/_/g, '/');\n const pad = normalized.length % 4 === 0 ? '' : '='.repeat(4 - (normalized.length % 4));\n return new Uint8Array(Buffer.from(normalized + pad, 'base64'));\n } catch {\n return null;\n }\n}\n\nasync function getSubtle(): Promise<{ subtle: SubtleCrypto }> {\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n return { subtle: globalThis.crypto.subtle };\n }\n const nodeCrypto = await import('node:crypto');\n return { subtle: nodeCrypto.webcrypto.subtle as SubtleCrypto };\n}\n","/**\n * MPP (Machine Payments Protocol) extractor.\n *\n * Wraps mppx (wevm) — pinned to 0.5.13, wrapped behind this adapter so\n * upgrades localise here. MPP launched March 18 2026 (Stripe + Tempo +\n * Paradigm), IETF draft-ryan-httpauth-payment-01.\n *\n * Flow:\n * Client → GET /resource\n * Server → 402 + WWW-Authenticate: Payment id=..., realm=..., method=tempo|stripe|...\n * Client → GET /resource with Authorization: Payment <base64url-json credential>\n * Server → 200 + Payment-Receipt: <base64url-json receipt>\n *\n * What we extract:\n * - Challenge: id, realm, method, intent, request{amount,currency,...}, expires, digest\n * - Credential: challenge + source (DID/chain-key) + payload (method-specific)\n * - Receipt: challengeId, method, reference (tx hash / pi_... ID), settlement\n * - Multi-method 402 offers (may be multiple WWW-Authenticate headers)\n *\n * What we do NOT verify here (pass-through):\n * - HMAC challenge binding (requires merchant's MPP_SECRET_KEY)\n * - Payment proof cryptography (Tempo tx sig, Stripe SPT, Lightning preimage)\n * — each requires upstream connectivity\n *\n * Verification (expiry + BodyDigest + source extraction) in mpp-verify.ts.\n */\n\nimport { Challenge, Credential, Receipt } from 'mppx';\n\nexport interface MPPChallengeSummary {\n id: string;\n realm: string;\n method: string;\n intent: string;\n /** Method-specific request data (amount, currency, recipient, etc.) */\n request: Record<string, unknown>;\n expires?: string;\n digest?: string;\n description?: string;\n opaque?: Record<string, string>;\n}\n\nexport interface MPPCredentialSummary {\n challenge: MPPChallengeSummary;\n /** DID or chain-native key identifying the payer. */\n source?: string;\n /** Method-specific payment proof (Tempo tx, SPT, Lightning preimage, etc.). */\n payload: unknown;\n}\n\nexport interface MPPReceiptSummary {\n method?: string;\n reference?: string;\n externalId?: string;\n status?: string;\n timestamp?: string;\n raw: Record<string, unknown>;\n}\n\nexport type MPPKind = 'challenge' | 'credential' | 'receipt' | 'error' | 'unknown';\n\nexport interface MPPRequestContext {\n kind: MPPKind;\n /** For 402 responses: one or more challenge offers. */\n challenges?: MPPChallengeSummary[];\n /** For requests with Authorization: Payment header. */\n credential?: MPPCredentialSummary;\n /** For 200 responses with Payment-Receipt header. */\n receipt?: MPPReceiptSummary;\n /** For problem+json error responses. */\n error?: { type?: string; title?: string; detail?: string };\n /** Detected payment methods offered (for multi-method 402). */\n offeredMethods?: string[];\n /** Raw body captured for BodyDigest verification in mpp-verify.ts. */\n rawBody?: string;\n}\n\nexport interface MPPRequestLike {\n method: string;\n url: string;\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n}\n\nexport interface MPPResponseLike {\n status: number;\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n}\n\n/**\n * Extract MPP context from an agent → merchant request.\n * Looks for `Authorization: Payment <credential>` header.\n */\nexport function extractMPPFromRequest(request: MPPRequestLike): MPPRequestContext | null {\n const auth = readHeader(request.headers, 'authorization');\n if (!auth || !/^\\s*Payment\\s+/i.test(auth)) return null;\n\n try {\n const credential = Credential.deserialize(auth);\n return {\n kind: 'credential',\n credential: {\n challenge: summarizeChallenge(credential.challenge),\n source: credential.source,\n payload: credential.payload,\n },\n rawBody: request.rawBody,\n };\n } catch {\n return { kind: 'error', error: { type: 'invalid-credential-encoding' } };\n }\n}\n\n/**\n * Extract MPP context from a merchant → agent response.\n * Handles 402 (challenge offers), 200 (receipt), 4xx (problem+json errors).\n */\nexport function extractMPPFromResponse(response: MPPResponseLike): MPPRequestContext | null {\n if (response.status === 402) {\n const challenges = collectChallenges(response);\n if (challenges.length === 0) return null;\n const methods = Array.from(new Set(challenges.map((c) => c.method)));\n return {\n kind: 'challenge',\n challenges,\n offeredMethods: methods,\n };\n }\n\n const receiptHeader = readHeader(response.headers, 'payment-receipt');\n if (receiptHeader) {\n try {\n const parsed = Receipt.deserialize(receiptHeader);\n const r = parsed as unknown as Record<string, unknown>;\n return {\n kind: 'receipt',\n receipt: {\n method: coerceString(r.method),\n reference: coerceString(r.reference),\n externalId: coerceString(r.externalId ?? r.external_id),\n status: coerceString(r.status),\n timestamp: coerceString(r.timestamp),\n raw: r,\n },\n };\n } catch {\n return { kind: 'error', error: { type: 'invalid-receipt-encoding' } };\n }\n }\n\n const contentType = readHeader(response.headers, 'content-type');\n if (contentType && /application\\/problem\\+json/i.test(contentType)) {\n const body =\n typeof response.body === 'object' && response.body !== null\n ? (response.body as Record<string, unknown>)\n : {};\n return {\n kind: 'error',\n error: {\n type: coerceString(body.type),\n title: coerceString(body.title),\n detail: coerceString(body.detail),\n },\n };\n }\n\n return null;\n}\n\n/**\n * Extract from either a request OR a response, auto-detecting which has MPP\n * artifacts. Convenience for pipeline callers.\n */\nexport function extractMPPContext(\n message:\n | { request: MPPRequestLike }\n | { response: MPPResponseLike }\n | (MPPRequestLike & Partial<MPPResponseLike>)\n): MPPRequestContext | null {\n if ('request' in message) return extractMPPFromRequest(message.request);\n if ('response' in message) return extractMPPFromResponse(message.response);\n if (typeof (message as MPPResponseLike).status === 'number') {\n return extractMPPFromResponse(message as MPPResponseLike);\n }\n return extractMPPFromRequest(message as MPPRequestLike);\n}\n\nfunction collectChallenges(response: MPPResponseLike): MPPChallengeSummary[] {\n const wwwAuth = readHeader(response.headers, 'www-authenticate');\n if (!wwwAuth) return [];\n const headers = new Headers();\n headers.set('www-authenticate', wwwAuth);\n\n const out: MPPChallengeSummary[] = [];\n try {\n const list = Challenge.fromHeadersList(headers);\n for (const ch of list) {\n out.push(summarizeChallenge(ch as unknown as Challenge.Challenge));\n }\n } catch {\n // fall through with empty list\n }\n return out;\n}\n\nfunction summarizeChallenge(\n ch: Challenge.Challenge | Record<string, unknown>\n): MPPChallengeSummary {\n const raw = ch as Record<string, unknown>;\n return {\n id: coerceString(raw.id) ?? '',\n realm: coerceString(raw.realm) ?? '',\n method: coerceString(raw.method) ?? '',\n intent: coerceString(raw.intent) ?? '',\n request: (raw.request as Record<string, unknown>) ?? {},\n expires: coerceString(raw.expires),\n digest: coerceString(raw.digest),\n description: coerceString(raw.description),\n opaque: raw.opaque as Record<string, string> | undefined,\n };\n}\n\nfunction readHeader(\n headers: Record<string, string | string[] | undefined>,\n name: string\n): string | undefined {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === name) {\n const raw = headers[key];\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw.join(', ');\n }\n }\n return undefined;\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n","/**\n * MPP verification — expiry + optional BodyDigest + source extraction.\n *\n * We do NOT verify the challenge's HMAC binding (needs merchant's secret)\n * or the cryptographic payment proof (per-method, requires upstream\n * connectivity). Those are the merchant's / settlement layer's job.\n *\n * Our job: structural correctness, expiry policy, tamper detection via\n * optional BodyDigest, and identity extraction for PDLSS binding.\n */\n\nimport { BodyDigest } from 'mppx';\nimport type { MPPRequestContext } from './mpp';\n\nexport interface MPPVerifyInput {\n context: MPPRequestContext;\n /** Raw request body to validate BodyDigest against, if the challenge declares one. */\n rawBody?: string;\n /** Seconds of clock-skew tolerance on challenge.expires. Default 300. */\n clockSkewSec?: number;\n /** Injectable for deterministic tests. */\n now?: () => number;\n}\n\nexport interface MPPVerifyResult {\n ok: boolean;\n expiryOk: boolean;\n bodyDigestOk: boolean | null;\n source?: string;\n method?: string;\n error?: string;\n}\n\nexport function verifyMPP(input: MPPVerifyInput): MPPVerifyResult {\n const { context } = input;\n const tolerance = input.clockSkewSec ?? 300;\n const nowSec = input.now ? input.now() : Math.floor(Date.now() / 1000);\n\n // Extract the challenge under test — for credential flow, from inside the\n // wrapped challenge; for bare challenge flow, from context.challenges[0].\n const challenge = context.credential?.challenge ?? (context.challenges && context.challenges[0]);\n const source = context.credential?.source;\n const method = challenge?.method;\n\n let expiryOk = true;\n if (challenge?.expires) {\n const parsedExpiry = Date.parse(challenge.expires);\n if (!Number.isFinite(parsedExpiry)) {\n return {\n ok: false,\n expiryOk: false,\n bodyDigestOk: null,\n source,\n method,\n error: 'unparseable challenge.expires',\n };\n }\n const expiresSec = Math.floor(parsedExpiry / 1000);\n if (nowSec > expiresSec + tolerance) {\n expiryOk = false;\n }\n }\n\n let bodyDigestOk: boolean | null = null;\n if (challenge?.digest && input.rawBody !== undefined) {\n try {\n if (!/^sha-256=/.test(challenge.digest)) {\n bodyDigestOk = false;\n } else {\n bodyDigestOk = BodyDigest.verify(challenge.digest as `sha-256=${string}`, input.rawBody);\n }\n } catch {\n bodyDigestOk = false;\n }\n }\n\n const ok = expiryOk && (bodyDigestOk === null || bodyDigestOk === true);\n const errors: string[] = [];\n if (!expiryOk) errors.push('challenge expired');\n if (bodyDigestOk === false) errors.push('body digest mismatch');\n\n return {\n ok,\n expiryOk,\n bodyDigestOk,\n source,\n method,\n error: errors.length > 0 ? errors.join('; ') : undefined,\n };\n}\n","/**\n * x402 (Coinbase / Linux Foundation x402 Foundation) extractor.\n *\n * Wraps @x402/core's schema parsers. x402 Foundation launched April 2 2026\n * with v2 adding network-agnostic identifiers + multiple facilitators +\n * Bazaar discovery. MPP (Machine Payments Protocol) is the IETF-formalised\n * superset of x402; this module normalizes x402 output to MPP-shape so\n * downstream pipeline code is uniform.\n *\n * Where x402 lives on the wire:\n * - 402 response body (v2) OR `X-PAYMENT-REQUIRED` header (v1) — PaymentRequired\n * - Request body (v2) OR `X-PAYMENT` header (v1, base64) — PaymentPayload\n */\n\nimport {\n validatePaymentRequired,\n validatePaymentPayload,\n type PaymentRequired,\n type PaymentPayload,\n type PaymentRequirements,\n} from '@x402/core/schemas';\nimport { safeBase64Decode } from '@x402/core/utils';\n\nexport type X402Kind = 'required' | 'payload' | 'error' | 'unknown';\n\nexport interface X402RequirementsSummary {\n scheme: string;\n network: string;\n asset: string;\n /** Normalized to string for v1/v2 compat — v1 uses maxAmountRequired, v2 uses amount. */\n amount: string;\n payTo: string;\n maxTimeoutSeconds?: number;\n resource?: string;\n description?: string;\n}\n\nexport interface X402RequestContext {\n kind: X402Kind;\n version: 1 | 2 | null;\n /** For 402 responses: the PaymentRequired body. */\n paymentRequired?: {\n resource: string;\n accepts: X402RequirementsSummary[];\n extensions?: Record<string, unknown>;\n error?: string;\n };\n /** For request body (v2) or X-PAYMENT header (v1 base64): the PaymentPayload. */\n paymentPayload?: {\n scheme: string;\n network: string;\n /** Free-form per-scheme payload (e.g. EIP-3009 authorization, Solana tx). */\n payload: Record<string, unknown>;\n extensions?: Record<string, unknown>;\n };\n error?: { type: string; detail?: string };\n /** Whether this was parsed from a header (v1 back-compat) or body (v2). */\n source: 'header' | 'body' | null;\n}\n\nexport interface X402RequestLike {\n method?: string;\n url?: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n}\n\nexport interface X402ResponseLike {\n status?: number;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n}\n\n/**\n * Extract x402 PaymentPayload from an agent → merchant request.\n * Checks v2 body (if it parses as PaymentPayload) and v1 X-PAYMENT header.\n */\nexport function extractX402FromRequest(request: X402RequestLike): X402RequestContext | null {\n const headerValue = readHeader(request.headers, 'x-payment');\n\n // v2 body path first\n if (request.body && typeof request.body === 'object') {\n const parsed = tryParsePayload(request.body);\n if (parsed) return buildPayloadContext(parsed, 'body');\n }\n\n // v1 header path\n if (headerValue) {\n try {\n const decoded = safeBase64Decode(headerValue);\n if (decoded) {\n const json = JSON.parse(decoded);\n const parsed = tryParsePayload(json);\n if (parsed) return buildPayloadContext(parsed, 'header');\n }\n } catch {\n return {\n kind: 'error',\n version: 1,\n source: 'header',\n error: { type: 'invalid-x402-payload' },\n };\n }\n }\n\n return null;\n}\n\n/**\n * Extract x402 PaymentRequired from a merchant → agent 402 response.\n */\nexport function extractX402FromResponse(response: X402ResponseLike): X402RequestContext | null {\n if (response.status !== 402) return null;\n\n // v2 body path\n if (response.body && typeof response.body === 'object') {\n const parsed = tryParseRequired(response.body);\n if (parsed) return buildRequiredContext(parsed, 'body');\n }\n\n // v1 header path\n const headerValue = readHeader(response.headers, 'x-payment-required');\n if (headerValue) {\n try {\n const decoded = safeBase64Decode(headerValue);\n if (decoded) {\n const json = JSON.parse(decoded);\n const parsed = tryParseRequired(json);\n if (parsed) return buildRequiredContext(parsed, 'header');\n }\n } catch {\n return {\n kind: 'error',\n version: 1,\n source: 'header',\n error: { type: 'invalid-x402-required' },\n };\n }\n }\n\n return null;\n}\n\nexport function extractX402Context(\n message:\n | { request: X402RequestLike }\n | { response: X402ResponseLike }\n | (X402RequestLike & Partial<X402ResponseLike>)\n): X402RequestContext | null {\n if ('request' in message) return extractX402FromRequest(message.request);\n if ('response' in message) return extractX402FromResponse(message.response);\n if (typeof (message as X402ResponseLike).status === 'number') {\n return extractX402FromResponse(message as X402ResponseLike);\n }\n return extractX402FromRequest(message as X402RequestLike);\n}\n\nfunction tryParseRequired(data: unknown): PaymentRequired | null {\n try {\n return validatePaymentRequired(data);\n } catch {\n return null;\n }\n}\n\nfunction tryParsePayload(data: unknown): PaymentPayload | null {\n try {\n return validatePaymentPayload(data);\n } catch {\n return null;\n }\n}\n\nfunction buildRequiredContext(\n parsed: PaymentRequired,\n source: 'header' | 'body'\n): X402RequestContext {\n const asRecord = parsed as unknown as Record<string, unknown>;\n const version = coerceVersion(asRecord.x402Version);\n const accepts = (asRecord.accepts as PaymentRequirements[] | undefined) ?? [];\n return {\n kind: 'required',\n version,\n source,\n paymentRequired: {\n resource: resolveResource(asRecord.resource),\n accepts: accepts.map(summarizeRequirement),\n extensions: asRecord.extensions as Record<string, unknown> | undefined,\n error: typeof asRecord.error === 'string' ? asRecord.error : undefined,\n },\n };\n}\n\nfunction buildPayloadContext(\n parsed: PaymentPayload,\n source: 'header' | 'body'\n): X402RequestContext {\n const asRecord = parsed as unknown as Record<string, unknown>;\n const version = coerceVersion(asRecord.x402Version);\n const accepted = asRecord.accepted as PaymentRequirements | undefined;\n const payload = (asRecord.payload as Record<string, unknown>) ?? {};\n return {\n kind: 'payload',\n version,\n source,\n paymentPayload: {\n scheme: accepted?.scheme ?? (typeof asRecord.scheme === 'string' ? asRecord.scheme : ''),\n network: accepted?.network ?? (typeof asRecord.network === 'string' ? asRecord.network : ''),\n payload,\n extensions: asRecord.extensions as Record<string, unknown> | undefined,\n },\n };\n}\n\nfunction summarizeRequirement(req: PaymentRequirements): X402RequirementsSummary {\n const r = req as unknown as Record<string, unknown>;\n const amount = (r.amount ?? r.maxAmountRequired ?? '0') as string;\n return {\n scheme: (r.scheme as string) ?? '',\n network: (r.network as string) ?? '',\n asset: (r.asset as string) ?? '',\n amount: String(amount),\n payTo: (r.payTo as string) ?? '',\n maxTimeoutSeconds: typeof r.maxTimeoutSeconds === 'number' ? r.maxTimeoutSeconds : undefined,\n resource: typeof r.resource === 'string' ? r.resource : undefined,\n description: typeof r.description === 'string' ? r.description : undefined,\n };\n}\n\nfunction resolveResource(v: unknown): string {\n if (typeof v === 'string') return v;\n if (v && typeof v === 'object' && 'url' in v && typeof (v as { url: unknown }).url === 'string') {\n return (v as { url: string }).url;\n }\n return '';\n}\n\nfunction coerceVersion(v: unknown): 1 | 2 | null {\n if (v === 1 || v === 2) return v;\n return null;\n}\n\nfunction readHeader(\n headers: Record<string, string | string[] | undefined> | undefined,\n name: string\n): string | undefined {\n if (!headers) return undefined;\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === name) {\n const raw = headers[key];\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw[0];\n }\n }\n return undefined;\n}\n","/**\n * VI (Verifiable Intent) 3-layer SD-JWT chain verification.\n *\n * VI chains: L1 (credential provider → wallet) → L2 (user → agent) → L3\n * (agent → merchant). L3 itself can split into L3a (payment mandate) + L3b\n * (checkout mandate) cross-referenced via transaction_id, with L3b carrying\n * a checkout_hash (VI constraint type 8) that must match SHA-256 of the L2\n * checkout disclosure.\n *\n * Signature primitives are delegated to @sd-jwt/core (via our extractor);\n * cnf.jwk chain-walking + cross-references + checkout_hash binding is\n * AstraSync-specific composition logic — that's the whitespace here.\n *\n * This module does NOT re-verify selective-disclosure hashes (the extractor\n * already applied them via @sd-jwt/decode). It DOES verify:\n * - cnf.jwk in L1 payload points to L2's signing key (thumbprint match)\n * - cnf.jwk in L2 payload points to L3's signing key\n * - L3a.transaction_id === L3b.transaction_id (when both present)\n * - L3b.checkout_hash === SHA-256(L2 canonical checkout disclosure) — type 8\n * - mandate-level `exp` is not in the past (beyond clock skew)\n *\n * Cryptographic signature verification on each layer uses the verifier\n * callback the caller supplies (e.g. resolves via @sd-jwt/core with the\n * right JWK from the L1 issuer's JWKS).\n */\n\nimport { createHash, webcrypto } from 'node:crypto';\nimport type { JWK } from 'jose';\n\nexport interface VILayer {\n /** Compact SD-JWT / JWS for this layer. */\n compact: string;\n /** Decoded JWT payload (already disclosure-merged). */\n payload: Record<string, unknown>;\n /** Decoded JWT header. */\n header: Record<string, unknown>;\n}\n\nexport interface VIVerifyInput {\n /**\n * Layers in chain order. L1 may be omitted when the caller has already\n * resolved the chain via a trusted wallet binding.\n */\n layers: {\n l1?: VILayer;\n l2: VILayer;\n l3a?: VILayer;\n l3b?: VILayer;\n };\n /**\n * Verifier callback invoked per layer. Should return true iff the layer's\n * JWS signature verifies against the resolved public key (for L2 this is\n * L1's cnf.jwk; for L3 this is L2's cnf.jwk; for L1 this is the issuer's\n * JWKS per `iss` claim).\n */\n verifySignature: (layer: VILayer, expectedKey: JWK | null) => Promise<boolean>;\n clockSkewSec?: number;\n now?: () => number;\n}\n\nexport interface VIVerifyResult {\n ok: boolean;\n checks: {\n l1SigOk: boolean | null;\n l2SigOk: boolean;\n l3aSigOk: boolean | null;\n l3bSigOk: boolean | null;\n l1BindsL2: boolean;\n l2BindsL3: boolean;\n l3aL3bTxnIdMatch: boolean | null;\n checkoutHashOk: boolean | null;\n expiryOk: boolean;\n };\n errors: string[];\n}\n\nexport async function verifyVIChain(input: VIVerifyInput): Promise<VIVerifyResult> {\n const errors: string[] = [];\n const tolerance = input.clockSkewSec ?? 300;\n const now = input.now ? input.now() : Math.floor(Date.now() / 1000);\n const { l1, l2, l3a, l3b } = input.layers;\n\n // Signature verification ---------------------------------\n const l1SigOk = l1 ? await input.verifySignature(l1, null) : null;\n if (l1 && !l1SigOk) errors.push('L1 signature invalid');\n\n const l1Cnf = extractCnfJwk(l1?.payload);\n const l2SigOk = await input.verifySignature(l2, l1Cnf ?? null);\n if (!l2SigOk) errors.push('L2 signature invalid');\n\n const l2Cnf = extractCnfJwk(l2.payload);\n const l3aSigOk = l3a ? await input.verifySignature(l3a, l2Cnf ?? null) : null;\n if (l3a && !l3aSigOk) errors.push('L3a signature invalid');\n const l3bSigOk = l3b ? await input.verifySignature(l3b, l2Cnf ?? null) : null;\n if (l3b && !l3bSigOk) errors.push('L3b signature invalid');\n\n // cnf.jwk binding ----------------------------------------\n let l1BindsL2 = true;\n if (l1Cnf) {\n const l2KeyFromHeader = await jwkForLayer(l2);\n l1BindsL2 = l2KeyFromHeader ? await thumbprintsMatch(l1Cnf, l2KeyFromHeader) : false;\n if (!l1BindsL2) errors.push('L1.cnf.jwk does not bind L2 signing key');\n }\n\n let l2BindsL3 = true;\n if (l2Cnf && (l3a || l3b)) {\n const l3Layer = l3a ?? l3b!;\n const l3KeyFromHeader = await jwkForLayer(l3Layer);\n l2BindsL3 = l3KeyFromHeader ? await thumbprintsMatch(l2Cnf, l3KeyFromHeader) : false;\n if (!l2BindsL3) errors.push('L2.cnf.jwk does not bind L3 signing key');\n }\n\n // L3a/L3b cross-reference --------------------------------\n let l3aL3bTxnIdMatch: boolean | null = null;\n if (l3a && l3b) {\n const a = coerceString(l3a.payload.transaction_id ?? l3a.payload.transactionId);\n const b = coerceString(l3b.payload.transaction_id ?? l3b.payload.transactionId);\n if (a && b) {\n l3aL3bTxnIdMatch = a === b;\n if (!l3aL3bTxnIdMatch) {\n errors.push(`L3a.transaction_id (${a}) does not match L3b.transaction_id (${b})`);\n }\n }\n }\n\n // checkout_hash (VI constraint type 8) -------------------\n let checkoutHashOk: boolean | null = null;\n if (l3b) {\n const declaredHash = coerceString(\n l3b.payload.checkout_hash ??\n l3b.payload.conditional_transaction_id ??\n (l3b.payload.payment_reference as Record<string, unknown> | undefined)?.checkout_hash\n );\n if (declaredHash) {\n const computed = computeCheckoutHashFromL2(l2);\n checkoutHashOk = computed ? declaredHash === computed : false;\n if (!checkoutHashOk) {\n errors.push('L3b.checkout_hash does not match SHA-256 of L2 checkout disclosure');\n }\n }\n }\n\n // Expiry policy ------------------------------------------\n const expiryOk = checkExpiryAcross([l1, l2, l3a, l3b], tolerance, now, errors);\n\n const ok =\n l1SigOk !== false &&\n l2SigOk &&\n l3aSigOk !== false &&\n l3bSigOk !== false &&\n l1BindsL2 &&\n l2BindsL3 &&\n l3aL3bTxnIdMatch !== false &&\n checkoutHashOk !== false &&\n expiryOk;\n\n return {\n ok,\n checks: {\n l1SigOk,\n l2SigOk,\n l3aSigOk,\n l3bSigOk,\n l1BindsL2,\n l2BindsL3,\n l3aL3bTxnIdMatch,\n checkoutHashOk,\n expiryOk,\n },\n errors,\n };\n}\n\nfunction extractCnfJwk(payload: Record<string, unknown> | undefined): JWK | null {\n if (!payload) return null;\n const cnf = payload.cnf as Record<string, unknown> | undefined;\n if (!cnf) return null;\n const jwk = cnf.jwk as JWK | undefined;\n return jwk ?? null;\n}\n\nasync function jwkForLayer(layer: VILayer): Promise<JWK | null> {\n // Prefer explicit cnf.jwk in the header, then payload; fallback to null.\n const fromHeader = extractCnfJwk(layer.header);\n if (fromHeader) return fromHeader;\n const fromPayload = extractCnfJwk(layer.payload);\n return fromPayload;\n}\n\nasync function thumbprintsMatch(a: JWK, b: JWK): Promise<boolean> {\n try {\n const ta = await jwkThumbprint(a);\n const tb = await jwkThumbprint(b);\n return ta === tb;\n } catch {\n return false;\n }\n}\n\n// RFC 7638 thumbprint: SHA-256 over the canonical JSON of required JWK members.\nasync function jwkThumbprint(jwk: JWK): Promise<string> {\n const canonical = canonicalJwk(jwk);\n const bytes = new TextEncoder().encode(JSON.stringify(canonical));\n const subtle = webcrypto.subtle as SubtleCrypto;\n const buffer = await new Promise<ArrayBuffer>((resolve, reject) => {\n const source = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(source).set(bytes);\n subtle.digest('SHA-256', source).then(resolve).catch(reject);\n });\n return Buffer.from(new Uint8Array(buffer)).toString('base64url').replace(/=+$/, '');\n}\n\nfunction canonicalJwk(jwk: JWK): Record<string, string> {\n // Per RFC 7638: members must appear in lexicographic order; only required\n // fields per kty are included.\n if (jwk.kty === 'EC') {\n return { crv: jwk.crv ?? '', kty: 'EC', x: jwk.x ?? '', y: jwk.y ?? '' };\n }\n if (jwk.kty === 'OKP') {\n return { crv: jwk.crv ?? '', kty: 'OKP', x: jwk.x ?? '' };\n }\n if (jwk.kty === 'RSA') {\n return { e: jwk.e ?? '', kty: 'RSA', n: jwk.n ?? '' };\n }\n return { kty: jwk.kty ?? '' };\n}\n\nfunction computeCheckoutHashFromL2(l2: VILayer): string | null {\n const checkoutDisclosure = (l2.payload.checkout ?? l2.payload.checkout_mandate) as unknown;\n if (!checkoutDisclosure) return null;\n const canonical = canonicalStringify(checkoutDisclosure);\n const hash = createHash('sha256').update(canonical).digest('base64url').replace(/=+$/, '');\n return hash;\n}\n\nfunction canonicalStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value);\n if (Array.isArray(value)) return '[' + value.map(canonicalStringify).join(',') + ']';\n const entries = Object.entries(value as Record<string, unknown>).sort(([a], [b]) =>\n a < b ? -1 : a > b ? 1 : 0\n );\n return (\n '{' + entries.map(([k, v]) => JSON.stringify(k) + ':' + canonicalStringify(v)).join(',') + '}'\n );\n}\n\nfunction checkExpiryAcross(\n layers: Array<VILayer | undefined>,\n toleranceSec: number,\n nowSec: number,\n errors: string[]\n): boolean {\n let ok = true;\n const names = ['L1', 'L2', 'L3a', 'L3b'];\n layers.forEach((layer, idx) => {\n if (!layer) return;\n const exp = toUnixSeconds(layer.payload.exp ?? layer.payload.expires);\n if (exp === undefined) return;\n if (nowSec > exp + toleranceSec) {\n errors.push(`${names[idx]} mandate expired at ${exp}`);\n ok = false;\n }\n });\n return ok;\n}\n\nfunction toUnixSeconds(v: unknown): number | undefined {\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (typeof v === 'string') {\n const asInt = Number(v);\n if (Number.isFinite(asInt) && asInt > 0) {\n return asInt >= 1e12 ? Math.floor(asInt / 1000) : Math.floor(asInt);\n }\n const parsed = Date.parse(v);\n if (Number.isFinite(parsed)) return Math.floor(parsed / 1000);\n }\n return undefined;\n}\n\nfunction coerceString(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n","/**\n * Commerce pipeline orchestrator.\n *\n * Ties together extractors + verifiers + identity binding + constraint\n * evaluation + trust signals into a single CommerceContext result.\n *\n * This is AstraSync whitespace: the orchestration over the library-backed\n * primitives. PR 3's Commerce Shield Lambda will call this per request;\n * the admin playground page will call it ad-hoc.\n *\n * Policy:\n * - Hard-deny (ok=false) on bad signatures, expired mandates, constraint\n * failures, identity cannot be bound.\n * - Trust signal (ok remains policy-driven) on ACP algorithm unsupported,\n * Stripe webhook HMAC fail, payment-token type unknown, cross-layer\n * identity mismatch.\n */\n\nimport type { ACPRequestContext } from './acp';\nimport { verifyACPSignature, type ACPVerifyResult } from './acp-verify';\nimport type { AP2MandateTriple } from './ap2';\nimport { verifyAP2Chain, type AP2ChainResult } from './ap2-verify';\nimport {\n evaluateVIConstraints,\n evaluatePaymentMethodAllowlist,\n evaluateSpendingLimit,\n type ConstraintEvalResult,\n type TransactionContext,\n} from './constraint-eval';\nimport { bindIdentity, type IdentityClaim, type IdentityResolver } from './identity-binding';\nimport { verifyMPP, type MPPVerifyResult } from './mpp-verify';\nimport type { MPPRequestContext } from './mpp';\nimport {\n mapACPRequestToPurpose,\n mapMPPRequestToPurpose,\n mapRFC9421TagToPurpose,\n mapUCPRequestToPurpose,\n mapVIMandateToPurpose,\n mapX402RequestToPurpose,\n type CommercePurpose,\n} from './purpose-mapping';\nimport {\n verifyRFC9421,\n type RFC9421VerifyResult,\n type RFC9421VerifyRequest,\n} from './rfc9421-verify';\nimport { verifyStripeWebhook, type VerifyStripeWebhookResult } from './stripe-webhook';\nimport {\n extractACPTransactionValue,\n extractMPPTransactionValue,\n extractUCPTransactionValue,\n extractVITransactionValue,\n extractX402TransactionValue,\n type TransactionValueContext,\n} from './transaction-value';\nimport type { UCPCheckoutContext } from './ucp';\nimport { verifyVIChain, type VIVerifyInput, type VIVerifyResult } from './vi-verify';\nimport type { VIExtractedClaims } from './vi';\nimport type { X402RequestContext } from './x402';\n\nexport type CommerceProtocol = 'vi' | 'ap2' | 'ucp' | 'acp' | 'agentpay' | 'tap' | 'mpp' | 'x402';\n\nexport interface CommercePipelineInput {\n protocol: CommerceProtocol;\n vi?: { claims: VIExtractedClaims; verifyInput?: VIVerifyInput };\n ap2?: { triple: AP2MandateTriple };\n ucp?: UCPCheckoutContext;\n acp?: {\n context: ACPRequestContext;\n verifyInput?: Parameters<typeof verifyACPSignature>[0];\n };\n rfc9421?: {\n request: RFC9421VerifyRequest;\n tag?: 'browse' | 'purchase' | string;\n verifyOptions: Parameters<typeof verifyRFC9421>[1];\n };\n mpp?: { context: MPPRequestContext; rawBody?: string };\n x402?: X402RequestContext;\n stripeWebhook?: { payload: string; signatureHeader: string; secret: string };\n transaction?: TransactionContext;\n registeredConstraints?: {\n allowedPaymentMethods?: string[];\n spendingLimit?: { amount?: number; currency?: string };\n };\n identityResolver?: IdentityResolver;\n clockSkewSec?: number;\n now?: () => number;\n}\n\nexport interface CommerceSignatureStack {\n vi?: VIVerifyResult;\n ap2?: AP2ChainResult;\n acp?: ACPVerifyResult;\n rfc9421?: RFC9421VerifyResult;\n mpp?: MPPVerifyResult;\n stripeWebhook?: VerifyStripeWebhookResult;\n}\n\nexport interface CommerceContext {\n protocol: CommerceProtocol;\n purpose: CommercePurpose | null;\n transactionValue?: TransactionValueContext;\n signatures: CommerceSignatureStack;\n identity?: {\n claims: IdentityClaim[];\n mappedAstraSyncAgentId?: string;\n mismatchAcrossLayers: boolean;\n };\n paymentToken?: {\n present: boolean;\n type: 'stripe-spt' | 'acp-vt' | 'tempo-tx' | 'other' | null;\n };\n mppMethodsOffered?: string[];\n constraints?: ConstraintEvalResult;\n receipt?: {\n method?: string;\n reference?: string;\n status?: string;\n timestamp?: string;\n };\n trustSignals: string[];\n timings: { extractMs: number; verifyMs: number; evalMs: number };\n /** False when any hard-deny rule fires. */\n ok: boolean;\n}\n\nexport async function runCommercePipeline(input: CommercePipelineInput): Promise<CommerceContext> {\n const trustSignals: string[] = [];\n const signatures: CommerceSignatureStack = {};\n const timings = { extractMs: 0, verifyMs: 0, evalMs: 0 };\n\n const extractStart = performance.now();\n const purpose = resolvePurpose(input);\n const transactionValue = resolveTransactionValue(input);\n const identityClaims = collectIdentityClaims(input);\n const paymentToken = resolvePaymentToken(input);\n timings.extractMs = Math.round(performance.now() - extractStart);\n\n const verifyStart = performance.now();\n let hardDeny = false;\n\n if (input.vi?.verifyInput) {\n signatures.vi = await verifyVIChain(input.vi.verifyInput);\n if (!signatures.vi.ok) hardDeny = true;\n }\n\n if (input.ap2) {\n signatures.ap2 = verifyAP2Chain({\n triple: input.ap2.triple,\n clockSkewSec: input.clockSkewSec,\n now: input.now,\n });\n if (!signatures.ap2.ok) hardDeny = true;\n }\n\n if (input.acp?.verifyInput) {\n signatures.acp = await verifyACPSignature(input.acp.verifyInput);\n if (!signatures.acp.ok && signatures.acp.timestampStale) hardDeny = true;\n if (signatures.acp.algorithm === 'unsupported') {\n trustSignals.push('acp-signature-algorithm-unsupported');\n } else if (!signatures.acp.ok) {\n hardDeny = true;\n }\n }\n\n if (input.rfc9421) {\n signatures.rfc9421 = await verifyRFC9421(input.rfc9421.request, input.rfc9421.verifyOptions);\n if (!signatures.rfc9421.ok) hardDeny = true;\n }\n\n if (input.mpp) {\n signatures.mpp = verifyMPP({\n context: input.mpp.context,\n rawBody: input.mpp.rawBody,\n clockSkewSec: input.clockSkewSec,\n now: input.now,\n });\n if (!signatures.mpp.ok) hardDeny = true;\n if (input.mpp.context.credential?.source) {\n trustSignals.push(`mpp-source-${shortSource(input.mpp.context.credential.source)}`);\n }\n }\n\n if (input.stripeWebhook) {\n signatures.stripeWebhook = verifyStripeWebhook(\n input.stripeWebhook.payload,\n input.stripeWebhook.signatureHeader,\n input.stripeWebhook.secret,\n { now: input.now ? () => input.now!() : undefined }\n );\n if (!signatures.stripeWebhook.ok) {\n trustSignals.push('stripe-webhook-hmac-failed');\n }\n }\n timings.verifyMs = Math.round(performance.now() - verifyStart);\n\n let identity: CommerceContext['identity'];\n if (input.identityResolver && identityClaims.length > 0) {\n const bound = await bindIdentity(identityClaims, input.identityResolver);\n identity = {\n claims: identityClaims,\n mappedAstraSyncAgentId: bound.mappedAstraSyncAgentId,\n mismatchAcrossLayers: bound.mismatchAcrossLayers,\n };\n if (bound.mismatchAcrossLayers) trustSignals.push('identity-mismatch-across-layers');\n } else if (identityClaims.length > 0) {\n identity = {\n claims: identityClaims,\n mappedAstraSyncAgentId: undefined,\n mismatchAcrossLayers: false,\n };\n }\n\n const evalStart = performance.now();\n const constraints = runConstraintEval(input);\n if (constraints && !constraints.ok) hardDeny = true;\n timings.evalMs = Math.round(performance.now() - evalStart);\n\n if (paymentToken?.type === 'stripe-spt') trustSignals.push('stripe-spt-present');\n if (paymentToken?.type === 'acp-vt') trustSignals.push('acp-vault-token-present');\n if (paymentToken?.type === 'tempo-tx') trustSignals.push('tempo-transaction-present');\n\n const mppReceipt = input.mpp?.context.receipt;\n\n return {\n protocol: input.protocol,\n purpose,\n transactionValue,\n signatures,\n identity,\n paymentToken,\n mppMethodsOffered: input.mpp?.context.offeredMethods,\n constraints,\n receipt: mppReceipt\n ? {\n method: mppReceipt.method,\n reference: mppReceipt.reference,\n status: mppReceipt.status,\n timestamp: mppReceipt.timestamp,\n }\n : undefined,\n trustSignals,\n timings,\n ok: !hardDeny,\n };\n}\n\nfunction resolvePurpose(input: CommercePipelineInput): CommercePurpose | null {\n if (input.vi?.claims.mandateType) {\n return mapVIMandateToPurpose(input.vi.claims.mandateType);\n }\n if (input.ap2?.triple.payment) return 'commerce.payment.execute';\n if (input.ap2?.triple.cart) return 'commerce.checkout.confirm';\n if (input.ap2?.triple.intent) return 'commerce.delegation.intent';\n if (input.ucp?.endpoint) {\n const [method, path] = input.ucp.endpoint.split(' ');\n return mapUCPRequestToPurpose(method ?? 'POST', path ?? '/');\n }\n if (input.acp?.context.endpoint) {\n // Extractor classifies as 'checkout_sessions.create|update|complete|cancel'\n // or 'delegate_payment'. Route each to the correct purpose.\n switch (input.acp.context.endpoint) {\n case 'checkout_sessions.create':\n return 'commerce.checkout.create';\n case 'checkout_sessions.update':\n return 'commerce.checkout.update';\n case 'checkout_sessions.complete':\n return 'commerce.payment.execute';\n case 'checkout_sessions.cancel':\n return 'commerce.checkout.cancel';\n case 'delegate_payment':\n return 'commerce.delegation.payment';\n default:\n return mapACPRequestToPurpose('POST', '/checkout_sessions');\n }\n }\n if (input.rfc9421?.tag) {\n return mapRFC9421TagToPurpose(\n input.rfc9421.tag === 'browse' || input.rfc9421.tag === 'purchase'\n ? (input.rfc9421.tag as 'browse' | 'purchase')\n : undefined\n );\n }\n if (input.mpp?.context.credential?.challenge || input.mpp?.context.challenges?.[0]) {\n const challenge = input.mpp.context.credential?.challenge ?? input.mpp.context.challenges?.[0];\n const amount = parseFloat(String(challenge?.request?.amount ?? 'NaN'));\n return mapMPPRequestToPurpose(\n challenge?.intent === 'session' ? 'session' : 'charge',\n Number.isFinite(amount) ? amount : undefined\n );\n }\n if (input.x402?.paymentRequired) {\n const amt = input.x402.paymentRequired.accepts[0]?.amount;\n return mapX402RequestToPurpose(Number(amt));\n }\n if (input.x402?.paymentPayload) return 'commerce.payment.execute';\n return null;\n}\n\nfunction resolveTransactionValue(\n input: CommercePipelineInput\n): TransactionValueContext | undefined {\n if (input.vi?.claims) {\n const v = extractVITransactionValue({\n constraints: input.vi.claims.constraints,\n l3aPaymentAmount: (input.vi.claims.constraints.paymentAmount &&\n typeof input.vi.claims.constraints.paymentAmount.max === 'number'\n ? {\n amount: input.vi.claims.constraints.paymentAmount.max,\n currency: input.vi.claims.constraints.paymentAmount.currency,\n }\n : undefined) as { amount?: number; currency?: string } | undefined,\n });\n if (v) return v;\n }\n if (input.ucp?.totals) {\n const v = extractUCPTransactionValue({ totals: input.ucp.totals });\n if (v) return v;\n }\n if (input.acp?.context.totals) {\n const v = extractACPTransactionValue({ totals: input.acp.context.totals });\n if (v) return v;\n }\n if (input.mpp?.context.credential?.challenge) {\n const ch = input.mpp.context.credential.challenge;\n const v = extractMPPTransactionValue({ method: ch.method, request: ch.request });\n if (v) return v;\n }\n if (input.x402?.paymentRequired) {\n const first = input.x402.paymentRequired.accepts[0];\n if (first) {\n const v = extractX402TransactionValue({\n maxAmountRequired: Number(first.amount),\n asset: first.asset,\n });\n if (v) return v;\n }\n }\n return undefined;\n}\n\nfunction collectIdentityClaims(input: CommercePipelineInput): IdentityClaim[] {\n const claims: IdentityClaim[] = [];\n if (input.vi?.claims.kid)\n claims.push({ protocol: 'vi', field: 'kid', value: input.vi.claims.kid });\n if (input.ap2?.triple) {\n const agentId =\n input.ap2.triple.intent?.agent_id ??\n input.ap2.triple.cart?.agent_id ??\n input.ap2.triple.payment?.agent_id;\n if (agentId) claims.push({ protocol: 'ap2', field: 'agent_id', value: agentId });\n }\n if (input.acp?.context.bearer) {\n claims.push({ protocol: 'acp', field: 'bearer', value: input.acp.context.bearer });\n }\n if (input.mpp?.context.credential?.source) {\n claims.push({ protocol: 'mpp', field: 'source', value: input.mpp.context.credential.source });\n }\n if (input.rfc9421) {\n // For RFC 9421 the kid is recorded after verify (result.kid); not collected here.\n }\n return claims;\n}\n\nfunction resolvePaymentToken(input: CommercePipelineInput): CommerceContext['paymentToken'] {\n if (input.acp?.context.paymentToken?.type) {\n return { present: true, type: input.acp.context.paymentToken.type };\n }\n const mppMethod = input.mpp?.context.credential?.challenge?.method;\n if (mppMethod === 'tempo') return { present: true, type: 'tempo-tx' };\n if (mppMethod === 'stripe') return { present: true, type: 'stripe-spt' };\n return undefined;\n}\n\nfunction runConstraintEval(input: CommercePipelineInput): ConstraintEvalResult | undefined {\n const transaction = input.transaction ?? {};\n const results: ConstraintEvalResult['results'] = {};\n const reasons: string[] = [];\n let hasAny = false;\n\n if (input.vi?.claims) {\n const viResult = evaluateVIConstraints({\n constraints: input.vi.claims.constraints,\n transaction,\n });\n for (const [k, v] of Object.entries(viResult.results)) {\n results[k] = v;\n if (!v.ok && v.reason) reasons.push(v.reason);\n }\n if (Object.keys(viResult.results).length > 0) hasAny = true;\n }\n\n const registered = input.registeredConstraints;\n if (registered?.allowedPaymentMethods) {\n const pm = evaluatePaymentMethodAllowlist({\n allowedMethods: registered.allowedPaymentMethods,\n requestedMethod: transaction.paymentMethod,\n });\n results.paymentMethod = pm;\n if (!pm.ok && pm.reason) reasons.push(pm.reason);\n hasAny = true;\n }\n if (registered?.spendingLimit) {\n const sp = evaluateSpendingLimit({\n limit: registered.spendingLimit,\n requested: { amount: transaction.amount, currency: transaction.currency },\n });\n results.spendingLimit = sp;\n if (!sp.ok && sp.reason) reasons.push(sp.reason);\n hasAny = true;\n }\n\n if (!hasAny) return undefined;\n return { ok: reasons.length === 0, results, reasons };\n}\n\nfunction shortSource(source: string): string {\n // Take first 16 chars sans scheme for trust-signal label readability.\n return source.replace(/^did:[a-z0-9]+:/, '').slice(0, 16);\n}\n","/**\n * Pluggable extractor registry for PR 3 Commerce Shield Lambda@Edge.\n *\n * Built-in extractors (VI, UCP, ACP, RFC 9421, MPP, x402, Stripe webhook)\n * are NOT auto-registered. PR 3 Lambda imports this module, picks the set\n * it wants, and calls registerTransportExtractor() for each.\n *\n * Re-registering by name replaces the prior extractor (idempotent).\n */\n\nexport interface ExtractorRequestLike {\n method?: string;\n url?: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n}\n\nexport interface TransportExtractor<T = unknown> {\n readonly name: string;\n match(request: ExtractorRequestLike): boolean;\n extract(request: ExtractorRequestLike): T | Promise<T> | null;\n}\n\nconst registry = new Map<string, TransportExtractor>();\n\nexport function registerTransportExtractor<T>(extractor: TransportExtractor<T>): void {\n if (!extractor || typeof extractor.name !== 'string' || extractor.name.length === 0) {\n throw new Error('registerTransportExtractor: extractor must have a non-empty name');\n }\n registry.set(extractor.name, extractor as TransportExtractor);\n}\n\nexport function getTransportExtractors(): ReadonlyArray<TransportExtractor> {\n return Array.from(registry.values());\n}\n\nexport function getTransportExtractor(name: string): TransportExtractor | undefined {\n return registry.get(name);\n}\n\nexport function clearTransportExtractors(): void {\n registry.clear();\n}\n\n/**\n * Helper: run all matching extractors against a request and return their\n * extracted contexts keyed by extractor name. Skips extractors whose\n * `match()` returns false.\n */\nexport async function runMatchingExtractors(\n request: ExtractorRequestLike\n): Promise<Record<string, unknown>> {\n const out: Record<string, unknown> = {};\n for (const extractor of registry.values()) {\n if (!extractor.match(request)) continue;\n const result = await extractor.extract(request);\n if (result !== null && result !== undefined) out[extractor.name] = result;\n }\n return out;\n}\n","/**\n * Visa JWKS registry resolver.\n *\n * Default endpoint: https://mcp.visa.com/.well-known/jwks (per Visa TAP spec).\n * Wraps jose.createRemoteJWKSet which handles caching + rotation natively.\n */\n\nimport { createRemoteJWKSet, type JWK } from 'jose';\nimport type { RegistryResolver, ResolveContext } from './types';\n\nconst DEFAULT_VISA_JWKS_URL = 'https://mcp.visa.com/.well-known/jwks';\n\nexport interface VisaRegistryOptions {\n jwksUrl?: string;\n cacheMaxAge?: number;\n cooldownDuration?: number;\n}\n\nexport function createVisaRegistry(options: VisaRegistryOptions = {}): RegistryResolver {\n const url = new URL(options.jwksUrl ?? DEFAULT_VISA_JWKS_URL);\n const jwks = createRemoteJWKSet(url, {\n cacheMaxAge: options.cacheMaxAge,\n cooldownDuration: options.cooldownDuration,\n });\n\n return {\n name: 'visa',\n async resolve(kid: string, context?: ResolveContext): Promise<JWK | null> {\n if (!kid) return null;\n try {\n const key = await jwks({\n kid,\n alg: context?.algorithm ?? 'ES256',\n typ: 'JWT',\n });\n return exportJwkFromKeyLike(key);\n } catch {\n return null;\n }\n },\n };\n}\n\nasync function exportJwkFromKeyLike(keyLike: unknown): Promise<JWK | null> {\n if (!keyLike) return null;\n // jose returns KeyObject or CryptoKey — both export via exportJWK at caller side.\n // Runtime shape check: if it already looks like a JWK, pass through.\n if (typeof keyLike === 'object' && 'kty' in (keyLike as object)) {\n return keyLike as JWK;\n }\n const { exportJWK } = await import('jose');\n try {\n return await exportJWK(keyLike as Parameters<typeof exportJWK>[0]);\n } catch {\n return null;\n }\n}\n","/**\n * Mastercard Agent Registry resolver — STUB.\n *\n * Mastercard Agent Pay is behind partnership (pilots Feb 2026, GA Q2 2026).\n * No public Agent Registry URL or open-source resolver exists as of April\n * 2026. This resolver accepts an optional `registryUrl` and, when absent,\n * returns null with a single one-time console.warn so callers can plumb\n * the flow end-to-end without a live registry.\n *\n * When Mastercard ships a public resolver or when a commercial relationship\n * provides a registry URL, pass it via `MastercardRegistryOptions.registryUrl`.\n * Response shape expected: { keys: JWK[] } (JWKS-style).\n */\n\nimport type { JWK } from 'jose';\nimport type { RegistryResolver } from './types';\n\nexport interface MastercardRegistryOptions {\n /** Partnership-provided registry URL. Without it, the resolver is inert. */\n registryUrl?: string;\n /** Cache TTL in seconds. Default 3600. */\n cacheTtlSec?: number;\n /** Fetch fn override for testing. */\n fetch?: typeof fetch;\n /** Silence the one-time warn (testing only). */\n silent?: boolean;\n}\n\ninterface CachedKey {\n jwk: JWK;\n expiresAt: number;\n}\n\nexport function createMastercardRegistry(\n options: MastercardRegistryOptions = {}\n): RegistryResolver {\n const cache = new Map<string, CachedKey>();\n const ttlSec = options.cacheTtlSec ?? 3600;\n const fetchFn = options.fetch ?? globalThis.fetch;\n let warned = false;\n\n return {\n name: 'mastercard',\n async resolve(kid: string): Promise<JWK | null> {\n if (!kid) return null;\n\n if (!options.registryUrl) {\n if (!warned && !options.silent) {\n warned = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[mastercard-registry] registryUrl not configured — key resolution disabled. ' +\n 'Kid lookups will return null until a partnership registry is supplied.'\n );\n }\n return null;\n }\n\n const cached = cache.get(kid);\n if (cached && cached.expiresAt > Date.now()) return cached.jwk;\n\n try {\n const res = await fetchFn(options.registryUrl);\n if (!res.ok) return null;\n const body = (await res.json()) as { keys?: JWK[] };\n const keys = body.keys ?? [];\n for (const k of keys) {\n if (k.kid === kid) {\n cache.set(kid, { jwk: k, expiresAt: Date.now() + ttlSec * 1000 });\n return k;\n }\n }\n return null;\n } catch {\n return null;\n }\n },\n };\n}\n","/**\n * Web Bot Auth registry resolver.\n *\n * IETF draft-meunier-web-bot-auth-architecture-05 + draft-meunier-http-\n * message-signatures-directory-01. Shared transport substrate under TAP,\n * Agent Pay, and Cloudflare Pay Per Crawl.\n *\n * Fetches a Web Bot Auth signature directory\n * (default: `<origin>/.well-known/http-message-signatures-directory`).\n * Shape per spec is a JWKS with Ed25519 keys.\n *\n * Wraps Cloudflare's `web-bot-auth` npm package where feasible; for raw\n * directory fetch + kid matching we use fetch + JSON since web-bot-auth's\n * higher-level API assumes a full request to verify.\n */\n\nimport type { JWK } from 'jose';\nimport type { RegistryResolver, ResolveContext } from './types';\n\nconst DIRECTORY_PATH = '/.well-known/http-message-signatures-directory';\n\nexport interface WebBotAuthRegistryOptions {\n /**\n * Optional explicit directory URL. When omitted, the resolver derives one\n * from `ResolveContext.origin` (e.g. the request URL's origin at verify time).\n */\n directoryUrl?: string;\n cacheTtlSec?: number;\n fetch?: typeof fetch;\n}\n\ninterface DirectoryCache {\n keys: JWK[];\n expiresAt: number;\n}\n\nexport function createWebBotAuthRegistry(\n options: WebBotAuthRegistryOptions = {}\n): RegistryResolver {\n const cache = new Map<string, DirectoryCache>();\n const ttlSec = options.cacheTtlSec ?? 3600;\n const fetchFn = options.fetch ?? globalThis.fetch;\n\n return {\n name: 'web-bot-auth',\n async resolve(kid: string, context?: ResolveContext): Promise<JWK | null> {\n if (!kid) return null;\n\n const directoryUrl = resolveDirectoryUrl(options.directoryUrl, context?.origin);\n if (!directoryUrl) return null;\n\n const cached = cache.get(directoryUrl);\n const now = Date.now();\n if (cached && cached.expiresAt > now) {\n return findKeyByKid(cached.keys, kid);\n }\n\n try {\n const res = await fetchFn(directoryUrl);\n if (!res.ok) return null;\n const body = (await res.json()) as { keys?: JWK[] };\n const keys = body.keys ?? [];\n cache.set(directoryUrl, { keys, expiresAt: now + ttlSec * 1000 });\n return findKeyByKid(keys, kid);\n } catch {\n return null;\n }\n },\n };\n}\n\nfunction resolveDirectoryUrl(\n explicit: string | undefined,\n origin: string | undefined\n): string | null {\n if (explicit) return explicit;\n if (!origin) return null;\n try {\n const url = new URL(origin);\n return `${url.origin}${DIRECTORY_PATH}`;\n } catch {\n return null;\n }\n}\n\nfunction findKeyByKid(keys: JWK[], kid: string): JWK | null {\n for (const k of keys) {\n if (k.kid === kid) return k;\n }\n return null;\n}\n","/**\n * MCP server-side helpers — companion to `transport/mcp.ts` (which handles the\n * agent-side `_meta.astrasync` block).\n *\n * Surfaces a body-aware policy hook the existing `createMiddleware` couldn't\n * provide — MCP traffic is JSON-RPC over a single endpoint (`/mcp`), so the\n * default route-pattern gating is too coarse: every request looks the same\n * URL-wise, but `initialize` is low-risk handshake while `tools/call` of a\n * payment tool is high-risk. Cohort-3 beta merchants flagged this 🟡 in the\n * v2.9.5 round.\n *\n * What lives here:\n * - `parseMcpJsonRpc(body)` — peels JSON-RPC method + tool name + agent\n * id without committing to a particular MCP\n * server framework.\n * - `mcpToPdlss(parsed)` — canonical mapping JSON-RPC method → PDLSS\n * purpose / action / resource. Doc-stable\n * so audits can correlate.\n * - `mcpRiskTier(parsed)` — recommended `minAccessLevel` per method\n * so a single MCP middleware can split\n * `initialize` / `tools/list` (low gate)\n * from `tools/call` (high gate).\n * - `MCP_VERIFIED_HOP_HEADER` — header convention for the dedupe pattern\n * when an MCP tool calls an inner REST hop.\n * - `serialize/parseVerifiedHop` helpers.\n *\n * The Express MCP adapter is in `adapters/mcp.ts` and consumes these.\n */\n\nimport type { AccessLevel } from '../types';\n\n/**\n * Header carrying upstream verify-access proof so an inner-hop REST endpoint\n * can dedupe (skip verify-access when the same ASTRA-id was already verified\n * a few ms earlier). Value format:\n *\n * {astraId};{sessionId};{checkedAt-ms}\n *\n * Receivers MUST validate that `checkedAt` is recent (≤ 60s window\n * recommended) and that `astraId` matches the agent identity claimed on the\n * inner hop. The header alone is NOT proof-of-identity — it's a dedupe\n * advisory. Pair with the existing X-Astra-Id auth.\n */\nexport const MCP_VERIFIED_HOP_HEADER = 'X-Astra-Verified-Hop';\n\n/** Default acceptable age (ms) for an X-Astra-Verified-Hop header. */\nexport const MCP_VERIFIED_HOP_MAX_AGE_MS = 60_000;\n\nexport interface VerifiedHopMarker {\n astraId: string;\n sessionId?: string;\n checkedAt: number; // epoch ms\n}\n\nexport function serializeVerifiedHop(marker: VerifiedHopMarker): string {\n return `${marker.astraId};${marker.sessionId ?? ''};${marker.checkedAt}`;\n}\n\nexport function parseVerifiedHop(value: string | undefined | null): VerifiedHopMarker | null {\n if (!value) return null;\n const parts = value.split(';');\n if (parts.length !== 3) return null;\n const [astraId, sessionId, checkedAtRaw] = parts;\n if (!astraId) return null;\n const checkedAt = Number(checkedAtRaw);\n if (!Number.isFinite(checkedAt) || checkedAt <= 0) return null;\n return {\n astraId,\n ...(sessionId ? { sessionId } : {}),\n checkedAt,\n };\n}\n\n/**\n * Returns true when `marker.astraId` matches the inner-hop's claimed\n * ASTRA-id AND the marker is recent enough. Inner-hop middleware uses this\n * to skip a duplicate verify-access call.\n */\nexport function isVerifiedHopValidFor(\n marker: VerifiedHopMarker | null,\n expectedAstraId: string,\n opts: { maxAgeMs?: number; now?: number } = {}\n): boolean {\n if (!marker) return false;\n if (marker.astraId !== expectedAstraId) return false;\n const maxAge = opts.maxAgeMs ?? MCP_VERIFIED_HOP_MAX_AGE_MS;\n const now = opts.now ?? Date.now();\n return now - marker.checkedAt <= maxAge && now >= marker.checkedAt;\n}\n\n/**\n * Output of `parseMcpJsonRpc`. Self-describing so the middleware doesn't have\n * to re-introspect the body to figure out gating.\n */\nexport interface ParsedMcpRequest {\n /** JSON-RPC method (e.g. `tools/call`, `initialize`, `tools/list`). */\n method: string;\n /** Set when method === 'tools/call'; the tool name from `params.name`. */\n toolName?: string;\n /** Initialize-specific protocolVersion handshake info, when present. */\n protocolVersion?: string;\n /**\n * Agent id read from the body, in priority order:\n * 1. `params._meta.astrasync.agentId` (the canonical SDK location, see\n * `transport/mcp.ts → setMcpMeta`)\n * 2. `params.arguments.agent_id` (legacy / hand-written tool callers)\n * Header-supplied id (X-Astra-Id) is read separately by the adapter and\n * compared to this for the mismatch check.\n */\n agentIdFromBody?: string;\n /**\n * Round-12 (F19) + round-13 (R13-1): purpose extracted from the MCP body\n * with the symmetric precedence chain. Sourced from `_meta.astrasync.purpose`\n * (canonical SDK location) OR `params.arguments.purpose` (legacy /\n * conventional callers). The discriminator is on `purposeSourceFromBody`.\n * Adapter combines this with the `X-Astra-Purpose` header (header wins)\n * before mapping; final fallback at `mcpToPdlss` is `'mcp_invoke'`.\n */\n purposeFromBody?: string;\n /** Which body location resolved `purposeFromBody`. */\n purposeSourceFromBody?: 'meta' | 'tool_argument';\n /**\n * Round-13 (R13-2): action extracted from the MCP body with the same\n * symmetric chain as purpose. Sourced from `_meta.astrasync.action`\n * (canonical) OR `params.arguments.action` (legacy). Adapter combines\n * with the `X-Astra-Action` header (header wins) before mapping; final\n * fallback at `mcpToPdlss` is the transport-layer default\n * (`tools/call:<toolname>` or just `<method>`).\n */\n actionFromBody?: string;\n /** Which body location resolved `actionFromBody`. */\n actionSourceFromBody?: 'meta' | 'tool_argument';\n /** True for handshake methods that must succeed before any tool call. */\n isInitialize: boolean;\n /** True for `tools/call`. */\n isToolCall: boolean;\n /** True for low-risk introspection (`tools/list`, `prompts/list`, etc.). */\n isIntrospection: boolean;\n}\n\n/**\n * Peel the JSON-RPC envelope. Returns `null` if the body isn't a JSON-RPC\n * request (callers can short-circuit with a 400 or treat as untyped traffic).\n *\n * Accepts both single-request and notification shapes. Batch requests are\n * NOT supported here — the verify-access contract is single-agent-per-call;\n * a batch body should be split before policy gating.\n */\nexport function parseMcpJsonRpc(body: unknown): ParsedMcpRequest | null {\n if (!body || typeof body !== 'object' || Array.isArray(body)) return null;\n const obj = body as Record<string, unknown>;\n if (obj.jsonrpc !== '2.0' && obj.jsonrpc !== '1.0') return null;\n const method = typeof obj.method === 'string' ? obj.method : null;\n if (!method) return null;\n const params = obj.params as Record<string, unknown> | undefined;\n\n // Tool-name lookup. MCP `tools/call` puts the tool under `params.name`.\n let toolName: string | undefined;\n if (method === 'tools/call' && params && typeof params.name === 'string') {\n toolName = params.name;\n }\n\n // protocolVersion only on the initialize request.\n let protocolVersion: string | undefined;\n if (method === 'initialize' && params && typeof params.protocolVersion === 'string') {\n protocolVersion = params.protocolVersion;\n }\n\n const meta = params?._meta as Record<string, unknown> | undefined;\n const astrasyncMeta = meta?.astrasync as Record<string, unknown> | undefined;\n const args = params?.arguments as Record<string, unknown> | undefined;\n\n // Agent-id lookup with documented precedence: _meta.astrasync.agentId\n // wins over params.arguments.agent_id. (The argument-shape uses\n // `agent_id` snake_case for legacy conventional callers; meta is the\n // canonical SDK location.)\n let agentIdFromBody: string | undefined;\n if (astrasyncMeta && typeof astrasyncMeta.agentId === 'string') {\n agentIdFromBody = astrasyncMeta.agentId;\n } else if (args && typeof args.agent_id === 'string') {\n agentIdFromBody = args.agent_id;\n }\n\n // Round-13 (R13-1, R13-2) — symmetric body-extraction for purpose +\n // action. Per `feedback_symmetric_fallbacks_for_symmetric_concepts.md`:\n // these two concepts are paired in the MCP middleware, so their\n // fallback chains MUST mirror each other exactly. Drift between them\n // generates the same support-ticket class repeatedly (\"I set X in\n // arguments and it didn't take\" — happened for purpose in round-12\n // post-F19, and was about to happen for action in round-13).\n //\n // Body precedence (applies to both): _meta.astrasync.<key> wins over\n // params.arguments.<key>. The discriminator is exported alongside the\n // value so the adapter can fold it into purposeSource / actionSource\n // for debug logging and adoption tracking.\n const purposeBodyResult = extractFromMcpBody(astrasyncMeta, args, 'purpose');\n const actionBodyResult = extractFromMcpBody(astrasyncMeta, args, 'action');\n\n const isInitialize = method === 'initialize';\n const isToolCall = method === 'tools/call';\n const isIntrospection =\n method === 'tools/list' ||\n method === 'prompts/list' ||\n method === 'resources/list' ||\n method === 'ping' ||\n method === 'notifications/initialized';\n\n return {\n method,\n ...(toolName ? { toolName } : {}),\n ...(protocolVersion ? { protocolVersion } : {}),\n ...(agentIdFromBody ? { agentIdFromBody } : {}),\n ...(purposeBodyResult.value ? { purposeFromBody: purposeBodyResult.value } : {}),\n ...(purposeBodyResult.source ? { purposeSourceFromBody: purposeBodyResult.source } : {}),\n ...(actionBodyResult.value ? { actionFromBody: actionBodyResult.value } : {}),\n ...(actionBodyResult.source ? { actionSourceFromBody: actionBodyResult.source } : {}),\n isInitialize,\n isToolCall,\n isIntrospection,\n };\n}\n\n/**\n * Shared body-extraction helper for the symmetric purpose + action\n * fallback chain (round-13 R13-1, R13-2). Returns the resolved value AND\n * the source discriminator so adapters can fold it into per-call debug\n * logs (`purpose_source` / `action_source`).\n *\n * Precedence:\n * 1. `params._meta.astrasync.<key>` — canonical SDK location, source: 'meta'\n * 2. `params.arguments.<key>` — legacy / conventional, source: 'tool_argument'\n * 3. neither present — value: undefined, source: undefined\n *\n * The HTTP-header tier (`X-Astra-<concept>`) is the adapter's job; this\n * helper only handles body sources. Adapters combine the two: header\n * wins over body. See `mcpToPdlss` for the final precedence assembly.\n */\nfunction extractFromMcpBody(\n astrasyncMeta: Record<string, unknown> | undefined,\n args: Record<string, unknown> | undefined,\n key: 'purpose' | 'action'\n): { value: string | undefined; source: 'meta' | 'tool_argument' | undefined } {\n if (astrasyncMeta && typeof astrasyncMeta[key] === 'string') {\n return { value: astrasyncMeta[key] as string, source: 'meta' };\n }\n if (args && typeof args[key] === 'string') {\n return { value: args[key] as string, source: 'tool_argument' };\n }\n return { value: undefined, source: undefined };\n}\n\n/**\n * PDLSS mapping for an MCP request. The platform's PDLSS taxonomy is\n * `purpose / action / resource`; for MCP traffic the audit-useful dimensions\n * are the JSON-RPC method and (for `tools/call`) the tool name. Doc-stable so\n * dashboards and audits can correlate consistently across cohort-3 partners.\n *\n * Rules:\n * - `purpose` is always `mcp_invoke` for MCP traffic — sets the high-level\n * PDLSS bucket.\n * - `action` is the JSON-RPC method, optionally `:tool_name` suffixed for\n * `tools/call`. Lets PDLSS allowlist specific tools.\n * - `resource` is `mcp:tool/<name>` for `tools/call`, `mcp:method/<method>`\n * otherwise. Lets PDLSS scope on tool identity.\n */\nexport interface McpPdlssMapping {\n purpose: string;\n action: string;\n resource: string;\n /**\n * Round-13 (R13-1 / R13-2): the resolution channel for purpose and\n * action — disjoint enums sharing the same structure per\n * `feedback_symmetric_fallbacks_for_symmetric_concepts.md`. Adapters\n * log both at debug level so partners can confirm header / body\n * pass-through, support can triage tickets, and we can watch the\n * `default_*` / `transport_layer` decay over time as integrations\n * mature.\n *\n * Round-12 (F19) used a narrower `purposeSource: 'header' |\n * 'tool_argument' | 'default_mcp_invoke'` — round-13 widens to also\n * carry the `_meta` source distinct from `tool_argument`, so the round-13\n * R13-1 fallback (which now reads both `_meta.astrasync.purpose` AND\n * `params.arguments.purpose`) can report WHICH body location resolved.\n */\n purposeSource: 'header' | 'meta' | 'tool_argument' | 'default_mcp_invoke';\n actionSource: 'header' | 'meta' | 'tool_argument' | 'transport_layer';\n}\n\n/**\n * Round-13 (R13-1 + R13-2) — canonical precedence chain documented ONCE,\n * applied identically to both purpose and action. Per\n * `feedback_symmetric_fallbacks_for_symmetric_concepts.md` — drift\n * between two paired concepts generates the same support-ticket class\n * repeatedly, so the resolution order is:\n *\n * 1. `X-Astra-<concept>` HTTP header (caller's explicit override)\n * 2. `params._meta.astrasync.<concept>` body field (canonical SDK location)\n * 3. `params.arguments.<concept>` body field (legacy / conventional)\n * 4. Transport-layer default:\n * purpose → 'mcp_invoke'\n * action → '<method>:<toolName>' (or just '<method>')\n *\n * The header tier is the adapter's job (it has `req.headers` access);\n * this function takes the resolved `headerPurpose` / `headerAction`\n * inputs and combines them with the body extraction already done in\n * `parseMcpJsonRpc`. The discriminator is reported on `purposeSource` /\n * `actionSource` for debug logging.\n */\nexport function mcpToPdlss(\n parsed: ParsedMcpRequest,\n headerPurpose?: string,\n headerAction?: string\n): McpPdlssMapping {\n const resource = parsed.toolName ? `mcp:tool/${parsed.toolName}` : `mcp:method/${parsed.method}`;\n\n // Purpose resolution: header > body (_meta, then tool_argument) > default\n let purpose: string;\n let purposeSource: McpPdlssMapping['purposeSource'];\n if (headerPurpose) {\n purpose = headerPurpose;\n purposeSource = 'header';\n } else if (parsed.purposeFromBody && parsed.purposeSourceFromBody) {\n purpose = parsed.purposeFromBody;\n purposeSource = parsed.purposeSourceFromBody;\n } else {\n purpose = 'mcp_invoke';\n purposeSource = 'default_mcp_invoke';\n }\n\n // Action resolution: identical chain, transport-layer default differs\n let action: string;\n let actionSource: McpPdlssMapping['actionSource'];\n if (headerAction) {\n action = headerAction;\n actionSource = 'header';\n } else if (parsed.actionFromBody && parsed.actionSourceFromBody) {\n action = parsed.actionFromBody;\n actionSource = parsed.actionSourceFromBody;\n } else {\n action = parsed.toolName ? `${parsed.method}:${parsed.toolName}` : parsed.method;\n actionSource = 'transport_layer';\n }\n\n return { purpose, action, resource, purposeSource, actionSource };\n}\n\n/**\n * Recommended minimum access level per method type. The MCP middleware uses\n * this to split low-risk handshake / introspection traffic from high-risk\n * tool execution — defect (a) from the cohort-3 review.\n *\n * - `initialize` / `notifications/initialized` → `none` (handshake must work for unregistered probes)\n * - `tools/list` / `prompts/list` / `resources/list` → `none` (introspection is public-surface)\n * - `ping` → `none`\n * - `resources/read` → `read-only`\n * - `tools/call` → `standard` (default — overridable per-tool)\n * - everything else → `standard` (least-privilege fallback)\n */\nexport function mcpRiskTier(parsed: ParsedMcpRequest): AccessLevel {\n if (parsed.isInitialize || parsed.method === 'notifications/initialized') return 'none';\n if (parsed.isIntrospection) return 'none';\n if (parsed.method === 'resources/read') return 'read-only';\n if (parsed.isToolCall) return 'standard';\n return 'standard';\n}\n","/**\n * AstraSync Universal Verification Gateway — MCP middleware\n *\n * Express-shaped middleware tailored to the JSON-RPC body of an MCP\n * (Model Context Protocol) endpoint. Closes the cohort-3 gaps the default\n * `createMiddleware` couldn't:\n *\n * (a) **Body-aware gating**. All MCP traffic targets the same `/mcp` URL.\n * The default route-pattern matcher can't tell `initialize` (low risk)\n * from `tools/call start_checkout` (high risk). This middleware peels\n * the JSON-RPC body and applies a per-method risk tier.\n *\n * (b) **PDLSS mapping**. Forwards `purpose=mcp_invoke`,\n * `action=method[:tool]`, `resource=mcp:tool/<name>` so audit traces\n * are stable across cohort-3 partners. See `transport/mcp-server.ts`\n * for the exact mapping.\n *\n * (c) **Inner-hop dedupe**. Outbound responses set\n * `X-Astra-Verified-Hop` so a downstream REST endpoint that the tool\n * calls can skip a duplicate verify-access. The receiving REST\n * middleware checks `parseVerifiedHop` and skips when valid.\n *\n * (d) **Header-vs-body identity precedence**. Reads ASTRA-id from\n * `X-Astra-Id` first, body second. If both are present and disagree,\n * returns a structured 400 by default (configurable). Pre-fix,\n * integrators had to re-discover this on their own.\n *\n * Usage:\n *\n * ```typescript\n * import express from 'express';\n * import { createMcpMiddleware } from '@astrasyncai/verification-gateway/mcp';\n *\n * const app = express();\n * app.use(express.json());\n *\n * app.post(\n * '/mcp',\n * createMcpMiddleware({\n * apiBaseUrl: 'https://astrasync.ai/api',\n * apiKey: process.env.ASTRASYNC_API_KEY,\n * // Optional per-tool overrides — tools not listed get the default tier\n * // from `mcpRiskTier` (`tools/call` → 'standard').\n * toolGates: {\n * start_checkout: 'standard',\n * confirm_purchase: 'full',\n * browse_catalog: 'read-only',\n * },\n * }),\n * yourMcpServerHandler,\n * );\n * ```\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type {\n GatewayConfig,\n AccessLevel,\n VerificationResult,\n EnhancedVerificationResult,\n} from '../types';\nimport {\n verify,\n extractCredentials,\n recordDecision,\n recordAnonymousLocalOverride,\n} from '../verify';\nimport { hasMinimumAccess } from '../access-levels';\nimport {\n parseMcpJsonRpc,\n mcpToPdlss,\n mcpRiskTier,\n serializeVerifiedHop,\n parseVerifiedHop,\n isVerifiedHopValidFor,\n MCP_VERIFIED_HOP_HEADER,\n type ParsedMcpRequest,\n} from '../transport/mcp-server';\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Express {\n interface Request {\n mcpRequest?: ParsedMcpRequest;\n }\n }\n}\n\nexport interface McpMiddlewareOptions extends GatewayConfig {\n /**\n * Per-tool override for the minimum access level. Tools not listed inherit\n * the default tier from `mcpRiskTier` (`tools/call` → `'standard'`). Use\n * for high-risk tools that demand `'full'` or low-risk read-only tools.\n */\n toolGates?: Record<string, AccessLevel>;\n /**\n * Per-method override (e.g. tighten `tools/list` to `'read-only'` if you\n * don't want unregistered probes seeing your tool catalogue). Matches by\n * exact JSON-RPC method string.\n */\n methodGates?: Record<string, AccessLevel>;\n /**\n * What to do when the agent id supplied in the X-Astra-Id header\n * disagrees with the agent id in the JSON-RPC body\n * (`params._meta.astrasync.agentId` or `params.arguments.agent_id`).\n *\n * - `'reject'` (default) — return 400 `AGENT_ID_MISMATCH`. Safest.\n * - `'prefer-header'` — log + verify against the header value. Keeps\n * bodies that were authored before X-Astra-Id was the canonical\n * identity slot working.\n * - `'prefer-body'` — log + verify against the body value. Useful in\n * reverse-proxy setups that strip auth headers.\n */\n onAgentIdMismatch?: 'reject' | 'prefer-header' | 'prefer-body';\n /** Skip verification + dedupe entirely. For testing. */\n skip?: boolean;\n /** Custom denied handler. Defaults to a structured JSON-RPC error response. */\n onDenied?: (result: VerificationResult, req: Request, res: Response) => void;\n /**\n * If `false`, don't trust an inbound `X-Astra-Verified-Hop` header (always\n * call verify-access). Default `true` — recommended for inner-hop endpoints\n * called by your own MCP tools.\n */\n trustVerifiedHop?: boolean;\n /** Window for accepting an upstream verified-hop marker. Default 60_000ms. */\n verifiedHopMaxAgeMs?: number;\n /**\n * Automatically record grant/deny decisions for every MCP call. Default\n * `true` — matches the express adapter.\n */\n recordDecisions?: boolean;\n /** Forward runtime challenge (default `true`). */\n enableRuntimeChallenge?: boolean;\n}\n\n/**\n * Default MCP denied handler.\n *\n * Round-10 (#47, O5): mirrors the express adapter — surfaces `failures[]`\n * and `correlationId` on the response so partners can render rich UX and\n * tie a denial to a log line. Also stamps `X-Astra-Gateway-Mode: enforced`\n * (#49/O10) so the header reliably distinguishes gate-evaluated denials\n * from gate-skipped pass-throughs.\n */\n/**\n * Round-13: shared single-value HTTP header reader. Same shape used for\n * both `X-Astra-Purpose` and `X-Astra-Action` extraction (symmetric\n * fallback chain — see `mcpToPdlss` for the full precedence rule).\n * Returns the first value if the header repeats (Express turns repeated\n * headers into an array); returns undefined when the header is absent.\n */\nfunction readSingleHeader(value: string | string[] | undefined): string | undefined {\n if (typeof value === 'string') return value;\n if (Array.isArray(value)) return value[0];\n return undefined;\n}\n\nfunction defaultMcpDenied(result: VerificationResult, req: Request, res: Response): void {\n // JSON-RPC error envelope so MCP-aware clients render it correctly.\n const id = (req.body as Record<string, unknown> | undefined)?.id ?? null;\n // Round-18 G4: see express.defaultOnDenied for full rationale on the\n // identity-vs-policy split → 401/403 mapping. Same logic here so MCP\n // clients get HTTP status semantics aligned with REST adapters.\n const status = !result.identityVerified ? 401 : 403;\n\n res.setHeader('X-Astra-Gateway-Mode', 'enforced');\n\n res.status(status).json({\n jsonrpc: '2.0',\n id,\n error: {\n // JSON-RPC error codes:\n // -32000 → unauthorized (no identity resolved)\n // -32001 → insufficient access (identity OK, policy denied)\n code: !result.identityVerified ? -32000 : -32001,\n message: result.denialReasons?.[0] ?? 'Access denied',\n data: {\n accessLevel: result.accessLevel,\n guidance: result.guidance,\n // Round-10: aggregated per-dimension detail + correlation handle.\n failures: result.failures,\n correlationId: result.correlationId,\n },\n },\n });\n}\n\n/**\n * Resolve the effective minimum access level for a parsed MCP request.\n * Order: per-tool override → per-method override → tier-default from\n * `mcpRiskTier`.\n *\n * v2.3.9 (defect #34) returns the SOURCE of the resolution alongside the\n * level so the gate-failure site can attribute a local override correctly\n * (`toolGate` / `methodGate` / `tier`) when reporting back to the\n * activity feed.\n */\nfunction resolveMinAccessLevel(\n parsed: ParsedMcpRequest,\n opts: { toolGates?: Record<string, AccessLevel>; methodGates?: Record<string, AccessLevel> }\n): { level: AccessLevel; source: 'toolGate' | 'methodGate' | 'tier' } {\n if (parsed.toolName && opts.toolGates && opts.toolGates[parsed.toolName] !== undefined) {\n return { level: opts.toolGates[parsed.toolName], source: 'toolGate' };\n }\n if (opts.methodGates && opts.methodGates[parsed.method] !== undefined) {\n return { level: opts.methodGates[parsed.method], source: 'methodGate' };\n }\n return { level: mcpRiskTier(parsed), source: 'tier' };\n}\n\n/**\n * Create the MCP middleware. Attach AFTER `express.json()` — the body must\n * already be a parsed object.\n */\nexport function createMcpMiddleware(options: McpMiddlewareOptions): RequestHandler {\n const {\n toolGates,\n methodGates,\n onAgentIdMismatch = 'reject',\n skip = false,\n onDenied = defaultMcpDenied,\n trustVerifiedHop = true,\n verifiedHopMaxAgeMs,\n recordDecisions,\n enableRuntimeChallenge = true,\n ...config\n } = options;\n\n return async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n if (skip) return next();\n\n const parsed = parseMcpJsonRpc(req.body);\n if (!parsed) {\n // Not a JSON-RPC body. Either the route is misconfigured or the\n // client sent a non-MCP payload. We don't 400 here — let the actual\n // MCP server handler render its own error so the middleware doesn't\n // pre-empt valid framework error shapes.\n if (config.setPassThroughHeader) {\n // Round-10 (#49, O10): `unenforced` describes the GATE state, not\n // the downstream response. Renamed from the ambiguous\n // `pass-through` (which partners read as \"request succeeded\").\n res.setHeader('X-Astra-Gateway-Mode', 'unenforced');\n res.setHeader('X-Astra-Gateway-Reason', 'non-jsonrpc-body');\n }\n return next();\n }\n req.mcpRequest = parsed;\n\n // ── Identity reconciliation (defect d) ─────────────────────────────\n // Header value is the SDK-canonical slot; body slot exists for legacy\n // hand-written tool callers and the MCP `_meta.astrasync.agentId`\n // convention.\n const headerRaw = req.headers['x-astra-id'] ?? req.headers['x-astra-agentid'];\n const headerAstraId =\n typeof headerRaw === 'string'\n ? headerRaw\n : Array.isArray(headerRaw)\n ? headerRaw[0]\n : undefined;\n const bodyAstraId = parsed.agentIdFromBody;\n\n let effectiveAstraId: string | undefined;\n if (headerAstraId && bodyAstraId && headerAstraId !== bodyAstraId) {\n if (onAgentIdMismatch === 'reject') {\n const id = (req.body as Record<string, unknown>)?.id ?? null;\n res.status(400).json({\n jsonrpc: '2.0',\n id,\n error: {\n code: -32602,\n message: 'AGENT_ID_MISMATCH',\n data: {\n detail:\n 'The agent id in the X-Astra-Id header disagrees with params._meta.astrasync.agentId / params.arguments.agent_id. Reconcile before calling the tool — see https://astrasync.ai/docs/mcp-integration#identity-reconciliation.',\n headerAstraId,\n bodyAstraId,\n },\n },\n });\n return;\n }\n effectiveAstraId = onAgentIdMismatch === 'prefer-header' ? headerAstraId : bodyAstraId;\n } else {\n effectiveAstraId = headerAstraId ?? bodyAstraId;\n }\n\n // ── Inner-hop dedupe (defect c) ────────────────────────────────────\n // If a trusted upstream MCP hop already verified this exact ASTRA-id\n // a few ms ago, we accept the marker and skip a redundant verify-access\n // call. Only valid when the header is fresh AND matches the agent id\n // we resolved above.\n if (trustVerifiedHop && effectiveAstraId) {\n const hopRaw = req.headers[MCP_VERIFIED_HOP_HEADER.toLowerCase()];\n const hopValue =\n typeof hopRaw === 'string' ? hopRaw : Array.isArray(hopRaw) ? hopRaw[0] : undefined;\n const marker = parseVerifiedHop(hopValue);\n if (\n isVerifiedHopValidFor(marker, effectiveAstraId, {\n ...(verifiedHopMaxAgeMs !== undefined ? { maxAgeMs: verifiedHopMaxAgeMs } : {}),\n })\n ) {\n // Skip verify-access — pass straight through. Don't re-emit the\n // header since the MCP framework will issue the response (the\n // outer hop already tagged it for any further inner hops).\n return next();\n }\n }\n\n // ── Resolve gating ─────────────────────────────────────────────────\n const { level: minAccessLevel, source: gateSource } = resolveMinAccessLevel(parsed, {\n toolGates,\n methodGates,\n });\n\n // ── Build verify-access request ────────────────────────────────────\n // Round-13 (R13-5) — credentials extraction hoisted above the\n // mcp-tier-none short-circuit (mirrors round-12 F9 express adapter\n // restructure). The `evaluateAlwaysIfCredentialed` flag lets the\n // caller turn unenforced tier-none calls into evaluated-not-enforced\n // calls when credentials are present, so the agent verification\n // result populates `req.agentVerification` for tier-aware handler\n // rendering (e.g. anonymous vs verified MCP tool listings).\n const credentials = extractCredentials(\n req.headers as Record<string, string | string[] | undefined>,\n req.query as Record<string, string | undefined>\n );\n // Override the SDK's default credential extraction with the resolved\n // ASTRA-id so the verify-access call sees the post-precedence value\n // (defect d). When neither header nor body supplied an id, the SDK's\n // anonymous-canonical-flow handles it.\n if (effectiveAstraId) credentials.astraId = effectiveAstraId;\n\n // Risk tier `none` short-circuit. Default behaviour: skip\n // verify-access (handshake / introspection must work for\n // unregistered probes). With `evaluateAlwaysIfCredentialed: true`\n // AND credentials present, fall through to verify-access for the\n // audit trail; the post-verify gate-skipping branch below handles\n // the rendering side. Round-12 F9 parity (closes the round-12\n // deferral).\n const shouldEnforce = minAccessLevel !== 'none';\n if (\n minAccessLevel === 'none' &&\n (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)\n ) {\n if (config.setPassThroughHeader) {\n // Round-10 (#49, O10): `unenforced` describes the GATE state, not\n // the downstream response.\n res.setHeader('X-Astra-Gateway-Mode', 'unenforced');\n res.setHeader('X-Astra-Gateway-Reason', 'mcp-tier-none');\n }\n return next();\n }\n\n // Round-12 (F19) + round-13 (R13-1, R13-2): symmetric purpose+action\n // resolution. Per `feedback_symmetric_fallbacks_for_symmetric_concepts.md`,\n // both concepts share the precedence chain documented at\n // `mcpToPdlss`:\n // header → _meta.astrasync.<concept> → params.arguments.<concept> → default\n //\n // Round-12 shipped purpose with `header → _meta → default`;\n // round-13 R13-1 closed the `params.arguments.purpose` fallback\n // gap. Round-13 R13-2 ships action with the same full chain in\n // one round (not staggered) to pre-empt the parallel \"I set\n // action in arguments and it didn't take\" support tickets.\n const headerPurpose = readSingleHeader(req.headers['x-astra-purpose']);\n const headerAction = readSingleHeader(req.headers['x-astra-action']);\n const pdlss = mcpToPdlss(parsed, headerPurpose, headerAction);\n\n // Telemetry: debug log per resolution. Adoption tracking, support\n // triage, and the `default_*` / `transport_layer` decay signals\n // all read this. Both purpose and action emit their source so we\n // can spot which integration path each partner is using.\n if (config.debug) {\n // eslint-disable-next-line no-console\n console.debug('[mcp-middleware] pdlss resolved', {\n purpose_source: pdlss.purposeSource,\n resolved_purpose: pdlss.purpose,\n action_source: pdlss.actionSource,\n resolved_action: pdlss.action,\n });\n }\n\n const counterpartyUrl =\n config.counterpartyUrl || `${req.protocol}://${req.get('host')}${req.path}`;\n const shouldRecordDecisions = recordDecisions !== false;\n\n const result = await verify(config, {\n credentials,\n purpose: pdlss.purpose,\n action: pdlss.action,\n resource: pdlss.resource,\n // Round-12 (F19): mark transport protocol separately from intent.\n // The MCP middleware always sets this to 'mcp'; non-MCP callers\n // leave it unset (server-side default is 'rest').\n invocationProtocol: 'mcp',\n createSession: shouldRecordDecisions,\n counterpartyUrl,\n counterpartyType: config.counterpartyType || 'mcp_server',\n enableRuntimeChallenge,\n callerMetadata: {\n sourceIp: req.ip,\n userAgent: req.headers['user-agent'] as string | undefined,\n host: req.headers.host as string | undefined,\n },\n });\n\n req.agentVerification = result;\n const sessionId = (result as EnhancedVerificationResult).sessionId;\n const correlationId = (result as EnhancedVerificationResult).correlationId;\n\n // v2.3.9 (defect #30): denied verifications short-circuit BEFORE the\n // gate-level comparison. See express.ts for the full rationale —\n // mirroring it here so the MCP path inherits the same belt-and-braces\n // protection against access-level/help-payload conflation.\n // Round-18 G4: short-circuit on either axis failing.\n if (!result.identityVerified || !result.policyAllowed) {\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'denied', result.denialReasons?.[0]).catch(() => {});\n }\n onDenied(result, req, res);\n return;\n }\n\n // Round-13 (R13-5): evaluation-without-enforcement parity with the\n // express F9 adapter. When the route is `none` but we ran\n // verify-access because `evaluateAlwaysIfCredentialed: true` AND\n // credentials were present, skip the gates and call next() — the\n // result is on `req.agentVerification` for the MCP handler to\n // render tier-aware responses (e.g. anonymous vs verified\n // tool-listing on the same `/mcp` endpoint).\n if (!shouldEnforce) {\n if (config.setPassThroughHeader) {\n res.setHeader('X-Astra-Gateway-Mode', 'enforced');\n res.setHeader('X-Astra-Gateway-Reason', 'evaluated-not-enforced');\n }\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'granted').catch(() => {});\n }\n return next();\n }\n\n if (!hasMinimumAccess(result.accessLevel, minAccessLevel)) {\n // Round-12 (F12): synthesise the structured failure entry so the\n // partner-facing response carries the same shape as every other\n // denial dimension. Guidance positions step-up only — increasing\n // trust score or lowering the route floor both read as gaming the\n // gate. Step-up flow ships separately this month.\n const insufficientFailure = {\n dimension: 'access_level.insufficient',\n message: `Tool requires accessLevel '${minAccessLevel}'; agent has '${result.accessLevel}'.`,\n guidance:\n \"Request elevated access via step-up verification (coming soon — ships this month). Step-up lets the agent owner approve a one-time elevation for this specific counterparty + purpose without changing the agent's baseline trust score.\",\n };\n result.failures = [...(result.failures ?? []), insufficientFailure];\n result.denialReasons = [...(result.denialReasons ?? []), insufficientFailure.message];\n\n // v2.3.9 (defect #34): server granted but local enforcement\n // (toolGate / methodGate / tier floor) is rejecting. Record this\n // as a local override so the activity feed surfaces the\n // dashboard-vs-runtime divergence as a distinct event.\n //\n // v2.3.10 (defect #34, round-4): anonymous traffic has no session\n // → fall back to `correlationId` and the sessionless local-override\n // endpoint. Authenticated traffic still uses sessionId/recordDecision.\n if (shouldRecordDecisions) {\n const overrideKind: 'toolGate' | 'methodGate' | 'other' =\n gateSource === 'toolGate'\n ? 'toolGate'\n : gateSource === 'methodGate'\n ? 'methodGate'\n : 'other';\n const override = {\n overriddenBy: overrideKind,\n ...(parsed.toolName && { toolName: parsed.toolName }),\n requestedLevel: minAccessLevel,\n grantedLevel: result.accessLevel,\n };\n if (sessionId) {\n recordDecision(config, sessionId, 'denied', result.denialReasons?.[0], override).catch(\n () => {}\n );\n } else if (correlationId) {\n recordAnonymousLocalOverride(\n config,\n correlationId,\n override,\n result.denialReasons?.[0]\n ).catch(() => {});\n }\n }\n onDenied(result, req, res);\n return;\n }\n\n // ── Tag the outbound response with X-Astra-Verified-Hop ────────────\n // Inner-hop REST endpoints called by this tool can read the header\n // and skip a duplicate verify-access. We set it on the response so\n // downstream proxies see it; tools that perform fetch() to an inner\n // hop should also forward it themselves (the MCP server framework\n // controls outbound calls — out of scope here).\n if (effectiveAstraId) {\n res.setHeader(\n MCP_VERIFIED_HOP_HEADER,\n serializeVerifiedHop({\n astraId: effectiveAstraId,\n ...(sessionId ? { sessionId } : {}),\n checkedAt: Date.now(),\n })\n );\n }\n\n if (shouldRecordDecisions && sessionId) {\n recordDecision(config, sessionId, 'granted').catch(() => {});\n }\n // v2.3.8 (defect #26): relay X-Astra-Unverified-Warning when the\n // server returned an audit-mode advisory.\n const enhancedResult = result as EnhancedVerificationResult;\n if (enhancedResult.warningHeader) {\n res.setHeader(enhancedResult.warningHeader.name, enhancedResult.warningHeader.value);\n }\n next();\n } catch (error) {\n // Fail open by default — the underlying MCP server handler still\n // exists and can apply its own access control. A logger hook is a\n // future enhancement.\n // eslint-disable-next-line no-console\n console.error('[VerificationGateway/MCP] Middleware error:', error);\n next();\n }\n };\n}\n\n// Re-export the helpers so consumers can mix-and-match (e.g. read the\n// verified-hop header themselves on a custom inner-hop handler).\nexport {\n parseMcpJsonRpc,\n mcpToPdlss,\n mcpRiskTier,\n serializeVerifiedHop,\n parseVerifiedHop,\n isVerifiedHopValidFor,\n MCP_VERIFIED_HOP_HEADER,\n};\nexport type { ParsedMcpRequest } from '../transport/mcp-server';\n","import type { ApiErrorResponse } from './types';\n\n/** Base error class for AstraSync SDK errors. */\nexport class AstraSyncError extends Error {\n public readonly code?: string;\n public readonly statusCode: number;\n\n constructor(message: string, statusCode: number, code?: string) {\n super(message);\n this.name = 'AstraSyncError';\n this.statusCode = statusCode;\n this.code = code;\n }\n}\n\n/** Thrown when KYD verification is required before agent registration. */\nexport class KYDRequiredError extends AstraSyncError {\n public readonly kydUrl: string;\n public readonly ownerNotified: boolean;\n\n constructor(response: ApiErrorResponse) {\n const kydUrl = response.kydUrl || 'https://astrasync.ai/developer-profile';\n super(\n `KYD verification required before registering agents.\\nComplete your KYD profile at: ${kydUrl}`,\n 403,\n 'KYD_REQUIRED'\n );\n this.name = 'KYDRequiredError';\n this.kydUrl = kydUrl;\n this.ownerNotified = response.ownerNotified || false;\n }\n}\n\n/** Thrown when authentication fails. */\nexport class AuthenticationError extends AstraSyncError {\n constructor(message: string) {\n super(message, 401, 'AUTH_FAILED');\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Thrown by `register({ waitForApproval: true })` when the owner denies the\n * pending registration request. The `reason` field, when present, mirrors the\n * deny note the owner left in the dashboard.\n */\nexport class RegistrationDeniedError extends AstraSyncError {\n public readonly requestId: string;\n public readonly reason?: string;\n\n constructor(requestId: string, reason?: string) {\n super(\n `Registration request ${requestId} was denied by the account owner.${reason ? ` Reason: ${reason}` : ''}`,\n 403,\n 'REGISTRATION_DENIED'\n );\n this.name = 'RegistrationDeniedError';\n this.requestId = requestId;\n this.reason = reason;\n }\n}\n\n/**\n * Thrown by `register({ waitForApproval: true })` when the pending request\n * passes its 14-day TTL with no owner decision. The agent must re-submit.\n */\nexport class RegistrationExpiredError extends AstraSyncError {\n public readonly requestId: string;\n\n constructor(requestId: string) {\n super(\n `Registration request ${requestId} expired before the owner approved it. Submit a new registration request.`,\n 410,\n 'REGISTRATION_EXPIRED'\n );\n this.name = 'RegistrationExpiredError';\n this.requestId = requestId;\n }\n}\n\n/**\n * Thrown by `register({ waitForApproval: true })` when the caller's local\n * `timeoutMs` elapses before the owner makes a decision. The request is still\n * live server-side — poll `pollRegistration(requestId)` to resume waiting, or\n * call `waitForApproval` again with a longer timeout.\n */\nexport class RegistrationTimeoutError extends AstraSyncError {\n public readonly requestId: string;\n\n constructor(requestId: string) {\n super(\n `Timed out waiting for owner approval of registration request ${requestId}. The request is still active server-side; poll the request to resume waiting.`,\n 408,\n 'REGISTRATION_TIMEOUT'\n );\n this.name = 'RegistrationTimeoutError';\n this.requestId = requestId;\n }\n}\n","import type {\n AstraSyncConfig,\n RegisterOptions,\n RegisterResult,\n WaitForApprovalOptions,\n PendingRegistrationResponse,\n PollRegistrationResult,\n RegistrationResponse,\n VerifyResponse,\n HealthResponse,\n ApiErrorResponse,\n AgentRecord,\n} from './types';\nimport {\n AstraSyncError,\n KYDRequiredError,\n AuthenticationError,\n RegistrationDeniedError,\n RegistrationExpiredError,\n RegistrationTimeoutError,\n} from './errors';\n\nconst DEFAULT_BASE_URL = 'https://astrasync.ai';\n\nconst sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\n/**\n * AstraSync SDK client for registering and managing AI agents.\n *\n * @example\n * ```typescript\n * const client = new AstraSync({ apiKey: 'kya_your_api_key' });\n * const result = await client.register({\n * name: 'My Agent',\n * model: { modelName: 'gpt-4o', modelProvider: 'openai', modelType: 'llm' },\n * });\n * ```\n *\n * For staging, pass `baseUrl: 'https://staging.astrasync.ai'`.\n */\nexport class AstraSync {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly email?: string;\n private readonly password?: string;\n private readonly privateKey?: string;\n private cachedJwt?: string;\n private jwtExpiresAt?: number;\n\n constructor(config: AstraSyncConfig = {}) {\n let raw = (config.baseUrl || process.env.ASTRASYNC_API_URL || DEFAULT_BASE_URL).replace(\n /\\/+$/,\n ''\n );\n // Round-10 (O2): tolerate the verify-side convention. `GatewayConfig.apiBaseUrl`\n // is documented as `https://astrasync.ai/api` (with /api), but\n // `AstraSyncConfig.baseUrl` is documented as the bare origin. Partners\n // passing the verify-style URL to the registration client hit a 404\n // because we'd then append `/api/agents/register` → double /api. Strip\n // a trailing `/api` and warn once so the partner can fix the source.\n if (raw.toLowerCase().endsWith('/api')) {\n raw = raw.slice(0, -'/api'.length);\n if (config.baseUrl && !config.silent) {\n // eslint-disable-next-line no-console\n console.warn(\n `[AstraSync] baseUrl '${config.baseUrl}' had a trailing /api — stripped to '${raw}'. ` +\n `Pass the bare origin (e.g. 'https://astrasync.ai' or 'https://staging.astrasync.ai') ` +\n `to AstraSync(). The /api suffix is the verify-gateway (GatewayConfig.apiBaseUrl) convention.`\n );\n }\n }\n this.baseUrl = raw;\n\n // Env fallback is opt-OUT: server-side wrappers (MCP tool handlers,\n // gateway adapters) pass `disableEnvFallback: true` so a no-credentials\n // call from a user-facing flow cannot silently authenticate as the host\n // process's platform-attribution key. CLIs / scripts that legitimately\n // rely on ASTRASYNC_API_KEY keep working under the default.\n this.apiKey = config.disableEnvFallback\n ? config.apiKey\n : config.apiKey || process.env.ASTRASYNC_API_KEY;\n this.email = config.email;\n this.password = config.password;\n this.privateKey = config.privateKey;\n\n // Defense-in-depth: warn when env fallback actually fires under the\n // default (non-strict) config. Surfaces the \"I'm running as platform\"\n // foot-gun before it becomes a security bug. Gated by !silent.\n if (\n !config.apiKey &&\n !config.disableEnvFallback &&\n process.env.ASTRASYNC_API_KEY &&\n !config.silent\n ) {\n // eslint-disable-next-line no-console\n console.warn(\n '[AstraSync] No apiKey passed to constructor; using process.env.ASTRASYNC_API_KEY. ' +\n 'If this code wraps user-facing flows (e.g. MCP tool handlers), pass ' +\n 'disableEnvFallback: true to prevent ambient credentials from impersonating callers. ' +\n 'See https://astrasync.ai/docs/agent-access#disableenvfallback for details.'\n );\n }\n\n if (!this.apiKey && !this.email) {\n throw new AuthenticationError(\n 'Authentication required. Provide apiKey, or email+password. ' +\n 'Set ASTRASYNC_API_KEY env var or pass config to constructor.'\n );\n }\n\n if (this.email && !this.password) {\n throw new AuthenticationError('Password is required when using email authentication.');\n }\n }\n\n /**\n * Register a new AI agent on the AstraSync KYA Platform.\n *\n * The backend response depends on auth context:\n * - **Crypto-keypair signed** (`privateKey` configured): synchronous 201,\n * returns `{ status: 'active', agent }`.\n * - **API-key only** (no signature): 202 pending, returns\n * `{ status: 'pending_approval', requestId, pollUrl, expiresAt }`. The\n * owner is notified by email and a dashboard alert is emitted; the agent\n * becomes active only after the owner approves.\n *\n * Blocking mode: pass `{ waitForApproval: true }` to have the SDK poll the\n * request until it resolves, then return the live agent record. The promise\n * rejects with `RegistrationDeniedError`, `RegistrationExpiredError`, or\n * `RegistrationTimeoutError` on the corresponding terminal states.\n *\n * @example Non-blocking (default — best for serverless / scheduled agents):\n * ```typescript\n * const result = await sdk.register({ name, pdlss });\n * if (result.status === 'pending_approval') {\n * storeRequestId(result.requestId);\n * return; // function exits; resume later via pollRegistration()\n * }\n * ```\n *\n * @example Blocking (best for long-running services + CLI):\n * ```typescript\n * const agent = await sdk.register({\n * name, pdlss, waitForApproval: true, timeoutMs: 600_000,\n * onPending: ({ ageMs }) => console.log(`waiting ${ageMs}ms`),\n * });\n * ```\n */\n async register(\n options: RegisterOptions & WaitForApprovalOptions\n ): Promise<RegisterResult | AgentRecord> {\n const body: Record<string, unknown> = {\n name: options.name,\n ...(options.description && { description: options.description }),\n ...(options.agentType && { agentType: options.agentType }),\n ...(options.apiEndpoint && { apiEndpoint: options.apiEndpoint }),\n ...(options.model && { model: options.model }),\n ...(options.framework && { framework: options.framework }),\n ...(options.protocols && { protocols: options.protocols }),\n ...(options.metadata && { metadata: options.metadata }),\n ...(options.pdlss && { pdlss: options.pdlss }),\n };\n\n const { status, body: raw } = await this.requestWithStatus<\n RegistrationResponse | PendingRegistrationResponse\n >('POST', '/api/agents/register', body);\n\n if (status === 201) {\n const activeBody = raw as RegistrationResponse;\n const active: RegisterResult = {\n status: 'active',\n agent: activeBody.data.agent,\n // Round-12 (F16): pass backend advisories through verbatim.\n // Pre-fix the SDK whitelisted five fields and silently dropped\n // `warnings`, which left partners with no signal that\n // `no_callback_endpoint` (or future advisories) had fired.\n ...(activeBody.warnings && { warnings: activeBody.warnings }),\n };\n return active;\n }\n\n // 202 Accepted — owner approval required.\n const pendingBody = raw as PendingRegistrationResponse;\n const pending: RegisterResult = {\n status: 'pending_approval',\n requestId: pendingBody.requestId,\n expiresAt: pendingBody.expiresAt,\n pollUrl: pendingBody.pollUrl,\n message: pendingBody.message,\n // Round-12 (F16): same pass-through on the pending path.\n ...(pendingBody.warnings && { warnings: pendingBody.warnings }),\n };\n\n if (!options.waitForApproval) return pending;\n\n return this.waitForApproval(pendingBody.requestId, options);\n }\n\n /**\n * Poll the current state of a pending-approval registration request.\n *\n * Useful for caller-driven polling when `waitForApproval: false` (the\n * default). The endpoint is unauthenticated — pass the `requestId` that\n * was returned from the 202 response.\n *\n * @returns `state: 'pending'` while awaiting; `'approved'` carries the\n * minted agent in `agent`; `'denied'` may carry the owner's\n * `reason`; `'expired'` is terminal after 14 days.\n */\n async pollRegistration(requestId: string): Promise<PollRegistrationResult> {\n const url = `${this.baseUrl}/api/agents/request-registration/${requestId}`;\n const res = await fetch(url, { headers: { Accept: 'application/json' } });\n if (!res.ok) {\n const errBody = (await res.json().catch(() => ({}))) as ApiErrorResponse;\n throw new AstraSyncError(\n errBody.error || `pollRegistration failed: ${res.status}`,\n res.status,\n errBody.code\n );\n }\n return (await res.json()) as PollRegistrationResult;\n }\n\n /**\n * Block until a pending registration request resolves to a terminal state.\n * Resolves to the live `AgentRecord` on approval; rejects with the matching\n * Registration*Error on deny/expire/timeout. Usually called via\n * `register({ waitForApproval: true })`, but exposed for callers that want\n * to fire-and-forget the initial register call and resume waiting later\n * (e.g. after restoring a stored `requestId` on cold start).\n */\n async waitForApproval(\n requestId: string,\n options: WaitForApprovalOptions = {}\n ): Promise<AgentRecord> {\n const timeoutMs = options.timeoutMs ?? 10 * 60 * 1000;\n const pollIntervalMs = options.pollIntervalMs ?? 5_000;\n const start = Date.now();\n const deadline = start + timeoutMs;\n\n while (Date.now() < deadline) {\n const result = await this.pollRegistration(requestId);\n const ageMs = Date.now() - start;\n options.onPending?.({ requestId, ageMs });\n\n if (result.state === 'approved') {\n if (!result.agent) {\n throw new AstraSyncError(\n `Registration ${requestId} reported approved but no agent payload returned.`,\n 500\n );\n }\n return result.agent;\n }\n if (result.state === 'denied') {\n throw new RegistrationDeniedError(requestId, result.reason);\n }\n if (result.state === 'expired') {\n throw new RegistrationExpiredError(requestId);\n }\n await sleep(pollIntervalMs);\n }\n throw new RegistrationTimeoutError(requestId);\n }\n\n /**\n * Look up an agent's public profile by ASTRA ID or UUID.\n */\n async verify(agentId: string): Promise<VerifyResponse> {\n return this.request<VerifyResponse>('GET', `/api/agents/verify/${agentId}`);\n }\n\n /**\n * Check API health.\n */\n async health(): Promise<HealthResponse> {\n const res = await fetch(`${this.baseUrl}/api/health/`);\n if (!res.ok) {\n throw new AstraSyncError(`Health check failed: ${res.status}`, res.status);\n }\n return res.json() as Promise<HealthResponse>;\n }\n\n // ── Private helpers ──────────────────────────────────────────────\n\n private async request<T>(method: string, endpoint: string, body?: unknown): Promise<T> {\n const { body: parsed } = await this.requestWithStatus<T>(method, endpoint, body);\n return parsed;\n }\n\n /**\n * Variant of {@link request} that also returns the HTTP status code, so\n * callers can branch on 201 vs 202 (or other success codes) without losing\n * type information about the response body.\n */\n private async requestWithStatus<T>(\n method: string,\n endpoint: string,\n body?: unknown\n ): Promise<{ status: number; body: T }> {\n const url = `${this.baseUrl}${endpoint}`;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Set auth header\n const token = await this.getAuthToken();\n headers['Authorization'] = `Bearer ${token}`;\n\n // Sign request if private key is configured\n if (this.privateKey) {\n const signature = await this.signRequest(method, endpoint, body || {});\n headers['X-AstraSync-Signature'] = signature;\n }\n\n const res = await fetch(url, {\n method,\n headers,\n ...(body ? { body: JSON.stringify(body) } : {}),\n });\n\n if (!res.ok) {\n const errorBody = (await res\n .json()\n .catch(() => ({ error: res.statusText }))) as ApiErrorResponse;\n\n // Handle KYD_REQUIRED specifically\n if (res.status === 403 && errorBody.code === 'KYD_REQUIRED') {\n throw new KYDRequiredError(errorBody);\n }\n\n throw new AstraSyncError(\n errorBody.error || `Request failed: ${res.status}`,\n res.status,\n errorBody.code\n );\n }\n\n return { status: res.status, body: (await res.json()) as T };\n }\n\n private async getAuthToken(): Promise<string> {\n // API key auth — use directly\n if (this.apiKey) {\n return this.apiKey;\n }\n\n // Email+password — login and cache JWT\n if (this.cachedJwt && this.jwtExpiresAt && Date.now() < this.jwtExpiresAt) {\n return this.cachedJwt;\n }\n\n const res = await fetch(`${this.baseUrl}/api/auth/login`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email: this.email, password: this.password }),\n });\n\n if (!res.ok) {\n const errorBody = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n throw new AuthenticationError(\n (errorBody.message as string) || (errorBody.error as string) || 'Login failed'\n );\n }\n\n const data = (await res.json()) as { data: { token: string } };\n this.cachedJwt = data.data.token;\n // Cache for 6 days (tokens expire in 7)\n this.jwtExpiresAt = Date.now() + 6 * 24 * 60 * 60 * 1000;\n\n return this.cachedJwt;\n }\n\n /**\n * Sign a request using secp256k1 (ethers.js).\n * Canonical message format: METHOD:ENDPOINT:SORTED_JSON_BODY\n * Must match apps/backend/src/services/signature-verify.service.ts exactly.\n */\n private async signRequest(method: string, endpoint: string, body: unknown): Promise<string> {\n const { Wallet } = await import('ethers');\n const sorted = this.sortObjectKeys(body);\n const canonical = `${method}:${endpoint}:${JSON.stringify(sorted)}`;\n const wallet = new Wallet(this.privateKey!);\n return wallet.signMessage(canonical);\n }\n\n /** Recursively sort object keys for canonical JSON representation. */\n private sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n if (Array.isArray(obj)) {\n return obj.map((item) => this.sortObjectKeys(item));\n }\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = this.sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n return sorted;\n }\n}\n","/**\n * Guidance envelope for credentials-required cases.\n *\n * Round-18 B3b: lifted from `apps/mcp-server/src/tools/agent-registration.ts`\n * (which had inlined the shape) so partners writing their own wrappers\n * (custom MCP servers, Express middleware around registration, gateway\n * adapters) consume a single source of truth instead of re-implementing the\n * five-step boilerplate.\n *\n * The envelope is what an agent (or wrapping MCP client) sees when it calls\n * `register_agent` with no AstraSync credentials. It tells the calling agent\n * (a) what failed (`status: 'credentials_required'`), (b) where to register\n * (`registrationUrl`), (c) where the relevant docs are (`documentationUrl`),\n * and (d) the ordered next-actions (`steps`).\n */\n\nexport interface GuidanceEnvelope {\n /**\n * Single-literal today. Expand to a union (e.g.\n * `'credentials_required' | 'kyd_required' | …`) when a second guidance\n * status emerges. Don't pre-emptively widen — the literal pins the shape.\n */\n status: 'credentials_required';\n message: string;\n guidance: {\n message: string;\n registrationUrl: string;\n documentationUrl: string;\n steps: string[];\n };\n}\n\nexport interface BuildGuidanceParams {\n /**\n * Bare origin of the AstraSync deployment the caller should register at,\n * e.g. `https://astrasync.ai` or `https://staging.astrasync.ai`. No\n * trailing slash, no `/api` suffix — registrationUrl and documentationUrl\n * are templated relative to this origin.\n */\n origin: string;\n /**\n * Overrides the top-level `message` (the short summary the agent sees).\n * Defaults to the error message from the SDK's `AuthenticationError`\n * when present, else a generic \"credentials required\" line.\n */\n message?: string;\n /**\n * Overrides the documentation path. Defaults to `/docs/agent-access`.\n */\n documentationPath?: string;\n}\n\n/**\n * Build the credentials-required guidance envelope.\n *\n * This is the canonical builder — MCP wrappers (`agent-registration.ts`),\n * Express middleware in custom integrations, and any other partner-side\n * wrapper that needs to surface \"you need to register\" should call this\n * rather than reconstructing the shape inline. Inline reconstruction\n * pre-round-18 led to drift between wrappers; this consolidates it.\n *\n * @example\n * ```ts\n * import { buildGuidance } from '@astrasyncai/verification-gateway';\n *\n * try {\n * const sdk = new AstraSync({ apiKey: callerApiKey, disableEnvFallback: true });\n * // ...\n * } catch (err) {\n * if (err instanceof AuthenticationError) {\n * return buildGuidance({ origin: 'https://astrasync.ai', message: err.message });\n * }\n * throw err;\n * }\n * ```\n */\nexport function buildGuidance(params: BuildGuidanceParams): GuidanceEnvelope {\n const origin = params.origin.replace(/\\/+$/, '');\n const docsPath = params.documentationPath ?? '/docs/agent-access';\n const message = params.message ?? 'AstraSync registration requires credentials.';\n\n return {\n status: 'credentials_required',\n message,\n guidance: {\n message:\n 'AstraSync registration requires credentials. Get an account + API key, then call register_agent again.',\n registrationUrl: `${origin}/register`,\n documentationUrl: `${origin}${docsPath.startsWith('/') ? docsPath : `/${docsPath}`}`,\n steps: [\n 'Visit registrationUrl and create an AstraSync account (or log in if you have one).',\n 'Generate an API key from Settings → API Keys.',\n 'Re-call register_agent with the apiKey populated.',\n 'After registration returns status: pending_approval, the owner approves via email.',\n 'Use poll_registration({ requestId }) to retrieve the astraId once approved.',\n ],\n },\n };\n}\n","/**\n * Agent-Side SDK Module\n *\n * Tools for AI agents to present credentials, handle challenges,\n * and interact with the AstraSync verification protocol.\n */\n\nexport { AgentClient } from './client';\nexport { ChallengeHandler } from './challenge-handler';\nexport { formatPDLSSForTransport, parsePDLSSFromTransport } from './pdlss-formatter';\nexport type { PDLSSConfig, TransportPDLSS } from './pdlss-formatter';\nexport { recordDecision } from './decision-client';\nexport { AstraSyncSdkError, OwnershipMismatchError } from './errors';\n","/**\n * Agent-side SDK errors.\n */\n\nexport class AstraSyncSdkError extends Error {\n readonly code: string;\n constructor(code: string, message: string) {\n super(message);\n this.name = 'AstraSyncSdkError';\n this.code = code;\n }\n}\n\n/**\n * Thrown when the API key used to initialise AgentClient is not owned by\n * the same account that registered the configured ASTRA-id. Blocks the\n * client from doing anything under a mismatched identity.\n */\nexport class OwnershipMismatchError extends AstraSyncSdkError {\n readonly astraId: string;\n\n constructor(astraId: string) {\n super(\n 'ownership_mismatch',\n `The configured API key does not own agent ${astraId}. Refusing to initialise.`\n );\n this.name = 'OwnershipMismatchError';\n this.astraId = astraId;\n }\n}\n","/**\n * AgentClient — Credential Presentation\n *\n * Agent-side SDK for automatically injecting AstraSync credentials\n * into outgoing requests across all supported protocols.\n */\n\nimport type { AstraSyncCredentials, ProtocolTransport } from '../types';\nimport { setHttpHeaders } from '../transport/http';\nimport { setA2AMetadata } from '../transport/a2a';\nimport { setMcpMeta } from '../transport/mcp';\nimport { applyCredentials } from '../transport';\nimport { OwnershipMismatchError } from './errors';\n\ninterface AgentClientConfig {\n agentId: string;\n verifyUrl?: string;\n challengeUrl?: string;\n pdlss?: AstraSyncCredentials['pdlss'];\n /** Base URL for AstraSync API (used for ownership check). Defaults to https://astrasync.ai/api */\n apiBaseUrl?: string;\n /** API key used to authenticate ownership check + other authenticated calls. */\n apiKey?: string;\n}\n\ninterface FetchOptions extends RequestInit {\n purpose?: string;\n action?: string;\n}\n\nexport class AgentClient {\n private credentials: AstraSyncCredentials;\n private apiBaseUrl: string;\n private apiKey: string | undefined;\n\n constructor(config: AgentClientConfig) {\n this.credentials = {\n agentId: config.agentId,\n verifyUrl: config.verifyUrl ?? 'https://astrasync.ai/api/agents/verify-access',\n challengeUrl: config.challengeUrl,\n pdlss: config.pdlss,\n };\n this.apiBaseUrl = config.apiBaseUrl ?? 'https://astrasync.ai/api';\n this.apiKey = config.apiKey;\n }\n\n /**\n * Async factory that validates the API key's account owns the configured\n * ASTRA-id before returning a usable client. Refuses to initialise on\n * mismatch so a stolen ASTRA-id cannot be paired with a valid (different)\n * API key.\n *\n * Set env `ASTRASYNC_SKIP_OWNERSHIP_CHECK=true` to bypass — intended for\n * test environments only.\n */\n static async create(config: AgentClientConfig): Promise<AgentClient> {\n const client = new AgentClient(config);\n\n const skip =\n typeof process !== 'undefined' && process.env?.ASTRASYNC_SKIP_OWNERSHIP_CHECK === 'true';\n if (skip) return client;\n\n if (!config.apiKey) {\n // Without an API key we cannot bind ownership. Surface this as the\n // same refusal so misconfigured clients fail loudly.\n throw new OwnershipMismatchError(config.agentId);\n }\n\n const owned = await client.verifyOwnership();\n if (!owned) throw new OwnershipMismatchError(config.agentId);\n return client;\n }\n\n /**\n * Calls GET /api/agents/:astraId/ownership with the configured API key.\n * Returns true only when the backend confirms this API key's account\n * owns the configured agent.\n */\n private async verifyOwnership(): Promise<boolean> {\n if (!this.apiKey) return false;\n const url = `${this.apiBaseUrl.replace(/\\/+$/, '')}/api/agents/${encodeURIComponent(\n this.credentials.agentId\n )}/ownership`;\n const resp = await fetch(url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n if (!resp.ok) return false;\n const body = (await resp.json().catch(() => null)) as {\n success?: boolean;\n data?: { owned?: boolean };\n } | null;\n return Boolean(body?.data?.owned);\n }\n\n /**\n * Make an HTTP request with AstraSync headers automatically injected.\n */\n async fetch(url: string, options?: FetchOptions): Promise<Response> {\n const { purpose, action, ...fetchOptions } = options ?? {};\n\n // Build credentials with optional overrides\n const creds: AstraSyncCredentials = { ...this.credentials };\n if (purpose) {\n creds.pdlss = {\n ...creds.pdlss,\n purpose: { category: purpose, action },\n };\n }\n\n // Inject AstraSync headers\n const existingHeaders: Record<string, string> = {};\n if (fetchOptions.headers) {\n if (fetchOptions.headers instanceof Headers) {\n fetchOptions.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n } else if (Array.isArray(fetchOptions.headers)) {\n for (const [key, value] of fetchOptions.headers) {\n existingHeaders[key] = value;\n }\n } else {\n Object.assign(existingHeaders, fetchOptions.headers);\n }\n }\n\n const enrichedHeaders = setHttpHeaders(existingHeaders, creds);\n\n return fetch(url, {\n ...fetchOptions,\n headers: enrichedHeaders,\n });\n }\n\n /**\n * Prepare A2A task metadata with AstraSync credentials.\n */\n prepareA2AMetadata(\n task: Record<string, unknown>,\n overrides?: { purpose?: string; action?: string }\n ): Record<string, unknown> {\n const creds = this.buildCredentials(overrides);\n return setA2AMetadata(task, creds);\n }\n\n /**\n * Prepare MCP params with AstraSync _meta.\n */\n prepareMcpMeta(\n params: Record<string, unknown>,\n overrides?: { purpose?: string; action?: string }\n ): Record<string, unknown> {\n const creds = this.buildCredentials(overrides);\n return setMcpMeta(params, creds);\n }\n\n /**\n * Generic: apply credentials to any protocol.\n */\n applyCredentials(\n protocol: ProtocolTransport,\n target: Record<string, unknown>,\n overrides?: { purpose?: string; action?: string }\n ): Record<string, unknown> {\n const creds = this.buildCredentials(overrides);\n return applyCredentials(protocol, target, creds);\n }\n\n private buildCredentials(overrides?: {\n purpose?: string;\n action?: string;\n }): AstraSyncCredentials {\n if (!overrides?.purpose) return this.credentials;\n\n return {\n ...this.credentials,\n pdlss: {\n ...this.credentials.pdlss,\n purpose: { category: overrides.purpose, action: overrides.action },\n },\n };\n }\n}\n","/**\n * ChallengeHandler — Agent-Side Runtime Challenge Responder\n *\n * Handles incoming runtime challenges from AstraSync's verification service.\n * Agents register pending counterparties before initiating contact,\n * then this handler validates and responds to challenges.\n */\n\ninterface ChallengePayload {\n challengeId: string;\n type: string;\n counterpartyId?: string | null;\n counterpartyUrl?: string | null;\n question?: string;\n issuedAt: string;\n expiresAt: string;\n}\n\ninterface ChallengeResponse {\n status: number;\n body: {\n challengeId: string;\n acknowledged: boolean;\n pendingCounterparties: string[];\n respondedAt: string;\n error?: string;\n };\n}\n\ninterface ChallengeHandlerConfig {\n agentId: string;\n}\n\nexport class ChallengeHandler {\n private agentId: string;\n private pendingCounterparties: Set<string> = new Set();\n\n constructor(config: ChallengeHandlerConfig) {\n this.agentId = config.agentId;\n }\n\n /**\n * Register a counterparty as pending (before initiating contact).\n */\n registerPending(counterpartyId: string): void {\n this.pendingCounterparties.add(counterpartyId);\n }\n\n /**\n * Remove a counterparty from pending list (after interaction complete).\n */\n removePending(counterpartyId: string): void {\n this.pendingCounterparties.delete(counterpartyId);\n }\n\n /**\n * Get current pending counterparties list.\n */\n getPendingList(): string[] {\n return [...this.pendingCounterparties];\n }\n\n /**\n * Express middleware for the challenge endpoint.\n * Mount at: app.post('/astrasync/challenge', handler.expressMiddleware())\n */\n expressMiddleware(): (req: { body: unknown }, res: { status: (code: number) => { json: (body: unknown) => void } }) => void {\n return (req, res) => {\n const result = this.handleChallenge(req.body);\n res.status(result.status).json(result.body);\n };\n }\n\n /**\n * Generic handler (framework-agnostic).\n * Returns { status, body } for the caller to send.\n */\n handleChallenge(body: unknown): ChallengeResponse {\n // Validate payload shape\n if (!body || typeof body !== 'object') {\n return {\n status: 400,\n body: {\n challengeId: '',\n acknowledged: false,\n pendingCounterparties: [],\n respondedAt: new Date().toISOString(),\n error: 'Invalid challenge payload',\n },\n };\n }\n\n const payload = body as ChallengePayload;\n\n if (!payload.challengeId || !payload.issuedAt || !payload.expiresAt) {\n return {\n status: 400,\n body: {\n challengeId: payload.challengeId ?? '',\n acknowledged: false,\n pendingCounterparties: [],\n respondedAt: new Date().toISOString(),\n error: 'Missing required challenge fields',\n },\n };\n }\n\n // Check if challenge has expired\n const now = new Date();\n const expiresAt = new Date(payload.expiresAt);\n if (now > expiresAt) {\n return {\n status: 410,\n body: {\n challengeId: payload.challengeId,\n acknowledged: false,\n pendingCounterparties: [],\n respondedAt: now.toISOString(),\n error: 'Challenge has expired',\n },\n };\n }\n\n // Respond with current pending list\n return {\n status: 200,\n body: {\n challengeId: payload.challengeId,\n acknowledged: true,\n pendingCounterparties: this.getPendingList(),\n respondedAt: now.toISOString(),\n },\n };\n }\n}\n","/**\n * PDLSS Formatter — Transport Format Conversion\n *\n * Converts between full PDLSS boundaries and compact transport format\n * used in HTTP headers, A2A metadata, and MCP _meta blocks.\n */\n\nimport type { AstraSyncCredentials } from '../types';\n\n/**\n * Full PDLSS configuration (as returned by the backend).\n */\nexport interface PDLSSConfig {\n purpose?: {\n categories?: string[];\n allowedActions?: string[];\n deniedActions?: string[];\n };\n duration?: {\n maxSessionDuration?: number;\n ttl?: number;\n allowedDays?: number[];\n allowedHours?: { start: number; end: number };\n };\n limits?: {\n autonomousThreshold?: number;\n stepUpThreshold?: number;\n approvalThreshold?: number;\n currency?: string;\n };\n scope?: {\n jurisdictions?: string[];\n resources?: string[];\n resourceTypes?: string[];\n };\n selfInstantiation?: {\n allowed: boolean;\n maxDepth?: number;\n maxSubAgents?: number;\n };\n}\n\n/**\n * Compact transport format (embedded in headers/metadata).\n */\nexport type TransportPDLSS = NonNullable<AstraSyncCredentials['pdlss']>;\n\n/**\n * Convert full PDLSS boundaries into compact transport format.\n * Used by AgentClient when building credential headers/metadata.\n */\nexport function formatPDLSSForTransport(pdlss: PDLSSConfig): TransportPDLSS {\n const transport: TransportPDLSS = {};\n\n // Purpose: pick the primary category and first allowed action\n if (pdlss.purpose?.categories?.length) {\n transport.purpose = {\n category: pdlss.purpose.categories[0],\n action: pdlss.purpose.allowedActions?.[0],\n };\n }\n\n // Duration: use the shorter of maxSessionDuration and ttl\n if (pdlss.duration) {\n const candidates: number[] = [];\n if (pdlss.duration.maxSessionDuration) candidates.push(pdlss.duration.maxSessionDuration);\n if (pdlss.duration.ttl) candidates.push(pdlss.duration.ttl);\n if (candidates.length > 0) {\n transport.duration = { maxSessionDuration: Math.min(...candidates) };\n }\n }\n\n // Scope: use the primary jurisdiction\n if (pdlss.scope?.jurisdictions?.length) {\n transport.scope = { jurisdiction: pdlss.scope.jurisdictions[0] };\n }\n\n return transport;\n}\n\n/**\n * Parse transport format back into full PDLSS config.\n * Used by counterparty-side when receiving credentials.\n */\nexport function parsePDLSSFromTransport(transport: TransportPDLSS): PDLSSConfig {\n const pdlss: PDLSSConfig = {};\n\n if (transport.purpose) {\n pdlss.purpose = {\n categories: [transport.purpose.category],\n allowedActions: transport.purpose.action ? [transport.purpose.action] : undefined,\n };\n }\n\n if (transport.duration) {\n pdlss.duration = {\n maxSessionDuration: transport.duration.maxSessionDuration,\n };\n }\n\n if (transport.scope) {\n pdlss.scope = {\n jurisdictions: transport.scope.jurisdiction ? [transport.scope.jurisdiction] : undefined,\n };\n }\n\n return pdlss;\n}\n","/**\n * Decision Client — Counterparty-Side Decision Recording\n *\n * Helper for counterparties to record their grant/deny decisions\n * back to AstraSync after receiving a verification result.\n */\n\nimport type { GatewayConfig } from '../types';\n\ninterface RecordDecisionParams {\n sessionId: string;\n decision: 'granted' | 'denied';\n reason?: string;\n tokenIssued?: boolean;\n auditId?: string;\n}\n\ninterface RecordDecisionResult {\n recorded: boolean;\n blockchainTxHash?: string;\n}\n\n/**\n * Record a counterparty's grant/deny decision for a verification session.\n * POST to /agents/verify-access/:sessionId/decision\n */\nexport async function recordDecision(\n config: GatewayConfig,\n params: RecordDecisionParams,\n): Promise<RecordDecisionResult> {\n const { sessionId, ...body } = params;\n const baseUrl = config.apiBaseUrl.replace(/\\/$/, '');\n const url = `${baseUrl}/agents/verify-access/${encodeURIComponent(sessionId)}/decision`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n }\n\n if (config.customHeaders) {\n Object.assign(headers, config.customHeaders);\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n throw new Error(\n `Failed to record decision for session ${sessionId}: ${response.status} ${errorText}`,\n );\n }\n\n const result = await response.json();\n\n return {\n recorded: result.recorded ?? true,\n blockchainTxHash: result.blockchainTxHash,\n };\n}\n"],"mappings":"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","names":["recordDecision","result","result","createMiddleware","matchRoute","findRouteConfig","DEFAULT_ROUTES_REFRESH_MS","createMiddleware","coerceString","stripQuery","extractSessionId","readHeader","coerceString","coerceString","coerceNumber","import_node_crypto","claim","import_decode","import_node_crypto","sha256Sync","applyDisclosures","coerceMandateType","coerceString","coerceNumber","readHeader","coerceString","import_mppx","readHeader","import_node_crypto","coerceString","toUnixSeconds","recordDecision","recordDecision"]}