{"version":3,"sources":["../src/attestation-receipt.ts"],"names":[],"mappings":";;;AA6BO,IAAM,wBAAA,GAA2B;AAQjC,IAAM,0BAAA,GAA6B;AAKnC,IAAM,kBAAA,GAAqB;AAAA;AAAA,EAEhC,eAAA,EAAiB,IAAA;AAAA;AAAA,EAEjB,iBAAA,EAAmB,IAAA;AAAA;AAAA,EAEnB,gBAAA,EAAkB,GAAA;AAAA;AAAA,EAElB,aAAA,EAAe,IAAA;AAAA;AAAA,EAEf,eAAA,EAAiB,EAAA;AAAA;AAAA,EAEjB,aAAA,EAAe,GAAA;AAAA;AAAA,EAEf,aAAA,EAAe;AACjB;AASA,IAAM,WAAW,CAAA,CACd,MAAA,EAAO,CACP,GAAA,GACA,GAAA,CAAI,kBAAA,CAAmB,eAAe,CAAA,CACtC,OAAO,CAAC,GAAA,KAAQ,IAAI,UAAA,CAAW,UAAU,GAAG,mBAAmB,CAAA;AAKlE,IAAM,MAAA,GAAS,CAAA,CACZ,MAAA,EAAO,CACP,KAAA;AAAA,EACC,wEAAA;AAAA,EACA;AACF,CAAA;AAWK,IAAM,+BAAA,GAAkC,EAC5C,MAAA,CAAO;AAAA;AAAA,EAEN,QAAQ,CAAA,CACL,MAAA,EAAO,CACP,GAAA,CAAI,CAAC,CAAA,CACL,GAAA,CAAI,kBAAA,CAAmB,eAAe,EACtC,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,CAAA;AAAA;AAAA,EAEnC,IAAA,EAAM,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,GAAA,CAAI,kBAAA,CAAmB,aAAa,CAAA;AAAA;AAAA,EAE5D,MAAA,EAAQ,CAAA,CACL,MAAA,EAAO,CACP,GAAA,EAAI,CACJ,GAAA,CAAI,kBAAA,CAAmB,aAAa,CAAA,CACpC,GAAA,CAAI,kBAAA,CAAmB,aAAa;AACzC,CAAC,EACA,MAAA;AAOI,IAAM,2BAAA,GAA8B,EAAE,MAAA,CAAO,CAAA,CAAE,QAAO,EAAG,CAAA,CAAE,SAAS;AASpE,IAAM,8BAAA,GAAiC,EAC3C,MAAA,CAAO;AAAA;AAAA,EAEN,GAAA,EAAK,QAAA;AAAA;AAAA,EAEL,GAAA,EAAK,QAAA;AAAA;AAAA,EAEL,KAAK,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA;AAAA,EAElC,KAAK,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA;AAAA,EAElC,GAAA,EAAK,MAAA;AAAA;AAAA,EAEL,GAAA,EAAK,EAAE,MAAA,EAAO,CAAE,IAAI,kBAAA,CAAmB,gBAAgB,EAAE,QAAA,EAAS;AAAA;AAAA,EAElE,GAAA,EAAK,4BAA4B,QAAA;AACnC,CAAC,EACA,MAAA;AA6BI,SAAS,iCAAiC,KAAA,EAA6C;AAC5F,EAAA,MAAM,MAAA,GAAS,8BAAA,CAA+B,SAAA,CAAU,KAAK,CAAA;AAC7D,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,EACvB;AACA,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA;AACxC,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,KAAA;AAAA,IACP,UAAA,EAAY,8BAAA;AAAA,IACZ,aAAA,EAAe,YAAY,OAAA,IAAW;AAAA,GACxC;AACF;AAQO,SAAS,2BAA2B,MAAA,EAAqD;AAC9F,EAAA,OAAO,8BAAA,CAA+B,SAAA,CAAU,MAAM,CAAA,CAAE,OAAA;AAC1D;AAQO,SAAS,kCAAkC,KAAA,EAA6C;AAC7F,EAAA,MAAM,MAAA,GAAS,+BAAA,CAAgC,SAAA,CAAU,KAAK,CAAA;AAC9D,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,EACvB;AACA,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA;AACxC,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,KAAA;AAAA,IACP,UAAA,EAAY,mCAAA;AAAA,IACZ,aAAA,EAAe,YAAY,OAAA,IAAW;AAAA,GACxC;AACF;AAQO,SAAS,4BACd,OAAA,EACsC;AACtC,EAAA,OAAO,+BAAA,CAAgC,SAAA,CAAU,OAAO,CAAA,CAAE,OAAA;AAC5D;AAiCO,SAAS,+BACd,MAAA,EAC0B;AAC1B,EAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AACxC,EAAA,MAAM,SAAA,GAAY,OAAO,SAAA,IAAa,GAAA;AAItC,EAAA,IAAI,mBAAmB,MAAA,CAAO,MAAA;AAC9B,EAAA,OAAO,gBAAA,CAAiB,QAAA,CAAS,GAAG,CAAA,EAAG;AACrC,IAAA,gBAAA,GAAmB,gBAAA,CAAiB,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,EACjD;AAGA,EAAA,MAAM,GAAA,GAA+B,EAAE,GAAG,MAAA,CAAO,UAAA,EAAW;AAC5D,EAAA,IAAI,OAAO,WAAA,EAAa;AACtB,IAAA,GAAA,CAAI,0BAA0B,IAAI,MAAA,CAAO,WAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,MAAA,GAAmC;AAAA,IACvC,GAAA,EAAK,gBAAA;AAAA,IACL,KAAK,MAAA,CAAO,QAAA;AAAA,IACZ,GAAA,EAAK,GAAA;AAAA,IACL,KAAK,GAAA,GAAM,SAAA;AAAA,IACX,KAAK,MAAA,CAAO,GAAA;AAAA,IACZ,GAAI,MAAA,CAAO,GAAA,IAAO,EAAE,GAAA,EAAK,OAAO,GAAA,EAAI;AAAA,IACpC,GAAI,OAAO,IAAA,CAAK,GAAG,EAAE,MAAA,GAAS,CAAA,IAAK,EAAE,GAAA;AAAI,GAC3C;AAEA,EAAA,OAAO,8BAAA,CAA+B,MAAM,MAAM,CAAA;AACpD;AAeO,SAAS,kBAAkB,MAAA,EAA0C;AAC1E,EAAA,OAAO,EAAE,KAAA,IAAS,MAAA,CAAA,IAAW,EAAE,KAAA,IAAS,MAAA,CAAA,IAAW,EAAE,SAAA,IAAa,MAAA,CAAA;AACpE;AAQO,SAAS,iBAAiB,MAAA,EAA0C;AACzE,EAAA,OAAO,KAAA,IAAS,MAAA,IAAU,KAAA,IAAS,MAAA,IAAU,SAAA,IAAa,MAAA;AAC5D","file":"attestation-receipt.mjs","sourcesContent":["/**\n * PEAC Attestation Receipt Types (v0.10.8+)\n *\n * Attestation receipts are lightweight signed tokens that attest to API\n * interactions WITHOUT payment fields. This is a distinct profile from\n * full payment receipts (PEACReceiptClaims).\n *\n * Use cases:\n * - API interaction logging with evidentiary value\n * - Middleware-issued receipts for non-payment flows\n * - Audit trails for agent/tool interactions\n *\n * Claims structure:\n * - Core JWT claims: iss, aud, iat, exp\n * - PEAC claims: rid (UUIDv7 receipt ID)\n * - Optional: sub, ext (extensions including interaction binding)\n *\n * @see docs/specs/ATTESTATION-RECEIPTS.md\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Attestation receipt type constant\n */\nexport const ATTESTATION_RECEIPT_TYPE = 'peac/attestation-receipt' as const;\n\n/**\n * Extension key for minimal interaction binding (middleware profile)\n *\n * This is a simplified binding used by middleware packages. For full\n * interaction evidence, use INTERACTION_EXTENSION_KEY from ./interaction.ts\n */\nexport const MIDDLEWARE_INTERACTION_KEY = 'org.peacprotocol/middleware-interaction@0.1';\n\n/**\n * Limits for attestation receipt fields (DoS protection)\n */\nexport const ATTESTATION_LIMITS = {\n  /** Maximum issuer URL length */\n  maxIssuerLength: 2048,\n  /** Maximum audience URL length */\n  maxAudienceLength: 2048,\n  /** Maximum subject length */\n  maxSubjectLength: 256,\n  /** Maximum path length in interaction binding */\n  maxPathLength: 2048,\n  /** Maximum method length */\n  maxMethodLength: 16,\n  /** Maximum HTTP status code */\n  maxStatusCode: 599,\n  /** Minimum HTTP status code */\n  minStatusCode: 100,\n} as const;\n\n// ============================================================================\n// Zod Schemas\n// ============================================================================\n\n/**\n * HTTPS URL validation (reused from validators.ts pattern)\n */\nconst httpsUrl = z\n  .string()\n  .url()\n  .max(ATTESTATION_LIMITS.maxIssuerLength)\n  .refine((url) => url.startsWith('https://'), 'Must be HTTPS URL');\n\n/**\n * UUIDv7 format validation\n */\nconst uuidv7 = z\n  .string()\n  .regex(\n    /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\n    'Must be UUIDv7 format'\n  );\n\n/**\n * Minimal interaction binding schema (for middleware use)\n *\n * This is a simplified version of full interaction evidence.\n * Contains only: method, path, status.\n *\n * Privacy note: Query strings are excluded by default to avoid\n * leaking sensitive data (API keys, tokens, PII in parameters).\n */\nexport const MinimalInteractionBindingSchema = z\n  .object({\n    /** HTTP method (uppercase, e.g., GET, POST) */\n    method: z\n      .string()\n      .min(1)\n      .max(ATTESTATION_LIMITS.maxMethodLength)\n      .transform((m) => m.toUpperCase()),\n    /** Request path (no query string by default) */\n    path: z.string().min(1).max(ATTESTATION_LIMITS.maxPathLength),\n    /** HTTP response status code */\n    status: z\n      .number()\n      .int()\n      .min(ATTESTATION_LIMITS.minStatusCode)\n      .max(ATTESTATION_LIMITS.maxStatusCode),\n  })\n  .strict();\n\n/**\n * Attestation receipt extensions schema\n *\n * Allows interaction binding and other namespaced extensions.\n */\nexport const AttestationExtensionsSchema = z.record(z.string(), z.unknown());\n\n/**\n * PEAC Attestation Receipt Claims schema\n *\n * This is the claims structure for attestation receipts - lightweight\n * receipts without payment fields. For full payment receipts, use\n * ReceiptClaimsSchema from ./validators.ts\n */\nexport const AttestationReceiptClaimsSchema = z\n  .object({\n    /** Issuer URL (normalized, no trailing slash) */\n    iss: httpsUrl,\n    /** Audience URL */\n    aud: httpsUrl,\n    /** Issued at (Unix seconds) */\n    iat: z.number().int().nonnegative(),\n    /** Expiration (Unix seconds) */\n    exp: z.number().int().nonnegative(),\n    /** Receipt ID (UUIDv7) */\n    rid: uuidv7,\n    /** Subject identifier (optional) */\n    sub: z.string().max(ATTESTATION_LIMITS.maxSubjectLength).optional(),\n    /** Extensions (optional) */\n    ext: AttestationExtensionsSchema.optional(),\n  })\n  .strict();\n\n// ============================================================================\n// TypeScript Types (inferred from Zod schemas)\n// ============================================================================\n\nexport type MinimalInteractionBinding = z.infer<typeof MinimalInteractionBindingSchema>;\nexport type AttestationExtensions = z.infer<typeof AttestationExtensionsSchema>;\nexport type AttestationReceiptClaims = z.infer<typeof AttestationReceiptClaimsSchema>;\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\n/**\n * Validation result type\n */\nexport interface AttestationValidationResult {\n  valid: boolean;\n  error_code?: string;\n  error_message?: string;\n}\n\n/**\n * Validate attestation receipt claims\n *\n * @param input - Raw input to validate\n * @returns Validation result\n */\nexport function validateAttestationReceiptClaims(input: unknown): AttestationValidationResult {\n  const result = AttestationReceiptClaimsSchema.safeParse(input);\n  if (result.success) {\n    return { valid: true };\n  }\n  const firstIssue = result.error.issues[0];\n  return {\n    valid: false,\n    error_code: 'E_ATTESTATION_INVALID_CLAIMS',\n    error_message: firstIssue?.message || 'Invalid attestation receipt claims',\n  };\n}\n\n/**\n * Check if an object is valid attestation receipt claims (non-throwing)\n *\n * @param claims - Object to check\n * @returns True if valid AttestationReceiptClaims\n */\nexport function isAttestationReceiptClaims(claims: unknown): claims is AttestationReceiptClaims {\n  return AttestationReceiptClaimsSchema.safeParse(claims).success;\n}\n\n/**\n * Validate minimal interaction binding\n *\n * @param input - Raw input to validate\n * @returns Validation result\n */\nexport function validateMinimalInteractionBinding(input: unknown): AttestationValidationResult {\n  const result = MinimalInteractionBindingSchema.safeParse(input);\n  if (result.success) {\n    return { valid: true };\n  }\n  const firstIssue = result.error.issues[0];\n  return {\n    valid: false,\n    error_code: 'E_ATTESTATION_INVALID_INTERACTION',\n    error_message: firstIssue?.message || 'Invalid interaction binding',\n  };\n}\n\n/**\n * Check if an object is valid minimal interaction binding (non-throwing)\n *\n * @param binding - Object to check\n * @returns True if valid MinimalInteractionBinding\n */\nexport function isMinimalInteractionBinding(\n  binding: unknown\n): binding is MinimalInteractionBinding {\n  return MinimalInteractionBindingSchema.safeParse(binding).success;\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Parameters for creating attestation receipt claims\n */\nexport interface CreateAttestationReceiptParams {\n  /** Issuer URL (will be normalized) */\n  issuer: string;\n  /** Audience URL */\n  audience: string;\n  /** Receipt ID (UUIDv7) */\n  rid: string;\n  /** Subject identifier (optional) */\n  sub?: string;\n  /** Interaction binding (optional) */\n  interaction?: MinimalInteractionBinding;\n  /** Additional extensions (optional) */\n  extensions?: Record<string, unknown>;\n  /** Expiration in seconds from now (default: 300) */\n  expiresIn?: number;\n}\n\n/**\n * Create validated attestation receipt claims\n *\n * @param params - Attestation receipt parameters\n * @returns Validated AttestationReceiptClaims\n * @throws ZodError if validation fails\n */\nexport function createAttestationReceiptClaims(\n  params: CreateAttestationReceiptParams\n): AttestationReceiptClaims {\n  const now = Math.floor(Date.now() / 1000);\n  const expiresIn = params.expiresIn ?? 300;\n\n  // Normalize issuer (remove trailing slashes)\n  // Using explicit loop instead of regex to avoid ReDoS with quantifiers\n  let normalizedIssuer = params.issuer;\n  while (normalizedIssuer.endsWith('/')) {\n    normalizedIssuer = normalizedIssuer.slice(0, -1);\n  }\n\n  // Build extensions\n  const ext: Record<string, unknown> = { ...params.extensions };\n  if (params.interaction) {\n    ext[MIDDLEWARE_INTERACTION_KEY] = params.interaction;\n  }\n\n  const claims: AttestationReceiptClaims = {\n    iss: normalizedIssuer,\n    aud: params.audience,\n    iat: now,\n    exp: now + expiresIn,\n    rid: params.rid,\n    ...(params.sub && { sub: params.sub }),\n    ...(Object.keys(ext).length > 0 && { ext }),\n  };\n\n  return AttestationReceiptClaimsSchema.parse(claims);\n}\n\n// ============================================================================\n// Type Guard for Receipt Profile Discrimination\n// ============================================================================\n\n/**\n * Check if claims are attestation-only (no payment fields)\n *\n * This helps discriminate between attestation receipts and\n * full payment receipts at runtime.\n *\n * @param claims - Receipt claims to check\n * @returns True if claims lack payment fields (amt, cur, payment)\n */\nexport function isAttestationOnly(claims: Record<string, unknown>): boolean {\n  return !('amt' in claims) && !('cur' in claims) && !('payment' in claims);\n}\n\n/**\n * Check if claims are payment receipt (has payment fields)\n *\n * @param claims - Receipt claims to check\n * @returns True if claims have payment fields\n */\nexport function isPaymentReceipt(claims: Record<string, unknown>): boolean {\n  return 'amt' in claims && 'cur' in claims && 'payment' in claims;\n}\n"]}