type JsonRecord = Record; export declare const VRP_RECEIPT_VERSION = "1.0"; /** * Normative v1 receipt schema (ADR 0010 D1–D5). This object is the source of * truth consumed by the verifier; `spec/vrp-receipt.v1.schema.json` is the * published artifact and is asserted byte-equal by a drift-guard test. */ export declare const VRP_RECEIPT_V1_SCHEMA: { readonly $schema: "http://json-schema.org/draft-07/schema#"; readonly $id: "https://vacationrentalprotocol.com/spec/vrp-receipt.v1.schema.json"; readonly title: "VRP Receipt Envelope v1"; readonly description: "Vacation Rental Protocol verifiable booking record. A versioned receipt with a FLAT array of attestations (ADR 0010 D1). Recursive sub-receipts and selective disclosure are reserved v2 extension points (present-but-empty in v1); a v1 verifier never recurses into them."; readonly type: "object"; readonly required: readonly ["vrp_receipt_version", "subject", "issuer", "attestations"]; readonly additionalProperties: true; readonly properties: { readonly vrp_receipt_version: { readonly type: "string"; readonly const: "1.0"; readonly description: "Receipt envelope version. v1 verifiers accept exactly \"1.0\"."; }; readonly subject: { readonly type: "object"; readonly description: "What the receipt is about (e.g. property, stay window, offer id). Kept generic so the envelope is not locked to vacation rentals."; }; readonly issuer: { readonly type: "object"; readonly description: "The node identity that assembled the receipt."; }; readonly attestations: { readonly type: "array"; readonly minItems: 1; readonly description: "FLAT list of attestations (ADR 0010 D1). A new trust layer = a new entry; no central approval."; readonly items: { readonly $ref: "#/definitions/attestation"; }; }; }; readonly definitions: { readonly attestation: { readonly type: "object"; readonly required: readonly ["layer", "valid_from", "valid_until"]; readonly additionalProperties: true; readonly properties: { readonly layer: { readonly type: "string"; readonly minLength: 1; readonly description: "Open vocabulary, e.g. \"offer\", \"transport\", \"payment\"."; }; readonly source: { readonly type: "string"; readonly description: "Where the verifying key is published for this attestation (e.g. a JWKS URL)."; }; readonly signature: { readonly type: "string"; readonly description: "The signed artifact as a compact JWS. v1 verifies the signature over the JWS bytes as received (ADR 0010 D5)."; }; readonly ref: { readonly type: "string"; readonly description: "Opaque correlator binding this attestation to an external object (offer id, transaction id, …)."; }; readonly valid_from: { readonly type: "string"; readonly format: "date-time"; readonly description: "Start of the attestation validity window (ADR 0010 D2; mandatory per attestation)."; }; readonly valid_until: { readonly type: "string"; readonly format: "date-time"; readonly description: "End of the attestation validity window (ADR 0010 D2; mandatory per attestation)."; }; readonly tlog: { readonly type: "object"; readonly description: "OPTIONAL transparency-log inclusion proof (ADR 0010 D3). A missing tlog is NOT a failure; a v1 verifier must not claim log-anchored properties for an attestation that lacks one."; }; readonly sub_receipt: { readonly description: "RESERVED v2 extension point (ADR 0010 D1). Recursive/chained receipts. A v1 verifier does not recurse into it."; readonly type: readonly ["object", "null"]; }; readonly disclosure: { readonly description: "RESERVED v2 extension point (ADR 0010 D1). Selective-disclosure / ZK pointers. Not interpreted by a v1 verifier."; readonly type: readonly ["object", "null"]; }; }; }; }; }; /** Per-attestation verification outcome (ADR 0010 D4). */ export type AttestationStatus = "verified" | "expired" | "unverifiable" | "invalid"; /** * Normative VRP receipt error registry (ADR 0010 D4). Seeded by unifying codes * that already exist in the reference implementation rather than inventing new * ones: VRP offer-layer codes come from `lib/vrp.ts` (`blocked_reason`) and * payment-layer codes from `lib/ap2.ts` (`reason`). */ export type VrpReceiptErrorCode = "unsupported_version" | "malformed_receipt" | "malformed_attestation" | "missing_validity_window" | "sig_invalid" | "sig_expired" | "not_yet_valid" | "key_unresolvable" | "layer_unverifiable" | "canonicalization_mismatch" | "agent_permission_denied" | "not_available" | "price_not_exact" | "direct_booking_url_missing" | "mandate_expired" | "mandate_missing_amount" | "invalid_charge_amount" | "amount_exceeds_mandate" | "currency_mismatch" | "merchant_mismatch" | "cart_mismatch"; export interface AttestationInput { layer: string; source?: string; signature?: string; ref?: string; valid_from?: string; valid_until?: string; tlog?: unknown; sub_receipt?: unknown; disclosure?: unknown; [key: string]: unknown; } export interface VrpReceiptInput { vrp_receipt_version: string; subject: JsonRecord; issuer: JsonRecord; attestations: AttestationInput[]; [key: string]: unknown; } export interface AttestationResult { index: number; layer: string; status: AttestationStatus; error: VrpReceiptErrorCode | null; kid: string | null; } export interface ReceiptVerificationResult { /** Structurally a valid v1 receipt (version + schema). */ receipt_valid: boolean; /** Every attestation verified AND fresh. Partial success is NOT full. */ fully_verified: boolean; attestations: AttestationResult[]; /** Envelope-level errors (empty when the structure is valid). */ errors: VrpReceiptErrorCode[]; } /** * Resolve the Ed25519 JWKS used to verify one attestation's signature. Kept as * an injected dependency so the verifier is pure and offline-testable; a caller * may resolve by fetching `attestation.source`, or supply a fixed key set. * Returning `null` marks the attestation `unverifiable` (key_unresolvable), * never `invalid` — absence of a key is not a forged signature. */ export type JwksResolver = (source: string | undefined, attestation: AttestationInput) => JsonRecord | null; export interface VerifyReceiptOptions { resolveJwks: JwksResolver; /** Override the clock (epoch ms) for deterministic freshness tests. */ now?: number; } /** * Verify a VRP receipt envelope. Returns per-attestation status with partial * verification (ADR 0010 D4) — `fully_verified` is true only when every * attestation is `verified`. Never throws on a well-formed call: malformed * input is reported as `receipt_valid: false` with an envelope error. */ export declare function verifyReceipt(receipt: unknown, opts: VerifyReceiptOptions): ReceiptVerificationResult; export {};