import { KeyObject } from 'node:crypto'; import type { Receipt, ReceiptStatus } from './domain.js'; import type { Currency } from './money.js'; export declare const RECEIPT_SIGNATURE_VERSION: 1; export interface SignatureBundle { readonly signature: string; readonly signatureVersion: number; readonly signingKeyId: string; } /** * A signer scoped to a single Stipend key id. Production deployments may * rotate keys by switching the signer at startup; receipts record which key * id signed them so verification can find the right public key later. */ export interface Signer { readonly keyId: string; readonly signatureVersion: number; sign(payload: string): SignatureBundle; } export interface Verifier { readonly keyId: string; verify(payload: string, signature: string): boolean; } interface Ed25519SignerOptions { readonly keyId: string; readonly privateKey: KeyObject | string | Buffer; readonly signatureVersion?: number; } interface Ed25519VerifierOptions { readonly keyId: string; readonly publicKey: KeyObject | string | Buffer; } export declare class Ed25519Signer implements Signer { readonly keyId: string; readonly signatureVersion: number; private readonly key; constructor(options: Ed25519SignerOptions); sign(payload: string): SignatureBundle; } export declare class Ed25519Verifier implements Verifier { readonly keyId: string; private readonly key; constructor(options: Ed25519VerifierOptions); verify(payload: string, signature: string): boolean; } /** * Generate a fresh Ed25519 keypair. Used by the keygen CLI helper. * Returns PEM-encoded keys, suitable for env / secret manager storage. */ export declare function generateEd25519Keypair(): { readonly privateKey: string; readonly publicKey: string; }; /** * Inputs required to derive a receipt's canonical signed payload. Both the * signer (when issuing a receipt) and the verifier (when re-deriving for * comparison) build the canonical string from exactly these fields. */ export interface ReceiptCanonicalInput { readonly id: string; readonly paymentId: string; readonly accountId: string; readonly status: ReceiptStatus; readonly amountCents: bigint; readonly currency: Currency; readonly providerRef: string | null; readonly entitlementsGranted: readonly string[]; readonly signedAt: string; } /** * Build the canonical JSON string for a receipt signature. * * Fields are snake_cased to match the TDD §5.1 signed-payload schema, even * though TypeScript uses camelCase internally. Any change to the field set * or its naming is a signature version bump. */ export declare function buildReceiptSignedPayload(receipt: ReceiptCanonicalInput): string; export interface VerifyReceiptResult { readonly valid: boolean; readonly keyId: string; readonly signatureVersion: number; readonly signedAt: string; readonly reason?: string; } export type PublicKeyResolver = (keyId: string) => KeyObject | string | Buffer | undefined; /** * Verify a receipt's signature without database access. * * Pass either a single public key (when the caller knows which key signed * the receipt) or a resolver function that maps the receipt's * `signingKeyId` to the matching public key (when supporting key * rotation). * * The function re-derives the canonical payload from the receipt's * fields, so an attacker cannot pass a tampered receipt with a matching * pre-canonicalized payload — the verifier always trusts the receipt's * fields as input and never trusts a payload string provided by the * caller. */ export declare function verifyReceipt(receipt: Receipt, keyOrResolver: KeyObject | string | Buffer | PublicKeyResolver): VerifyReceiptResult; export {}; //# sourceMappingURL=signing.d.ts.map