/** * Verify a vault-provider CWT bearer (RFC 8392 / COSE Sign1, ES256K): checks the * signature against the VP's attested ephemeral key (see {@link ./serverIdentity}) * and binds `iss`/`sub`/`aud` to the pinned VP, subject, and depositor. TS port * of btc-vault `client.rs::validate_token_with_public_key_at_time`. * * Divergence from that reference: the FE does NOT clock-gate `nbf`/`iat`. The VP * server is the temporal authority and re-checks `nbf`/`exp` on every gated call; * re-checking `nbf` against the browser clock only bricked freshly minted tokens * on benign skew. `exp` (wide window) and the structural `iat <= exp` are kept. * * @module tbv/core/clients/vault-provider/auth/verifyDepositorCwt */ /** CWT `sub` value for JSON-RPC-subject tokens (`auth_createDepositorToken`). */ export declare const CWT_SUBJECT_JSONRPC = "vaultd-jsonrpc"; /** CWT `sub` value for gRPC-subject tokens (`auth_createDepositorTokenGrpc`). */ export declare const CWT_SUBJECT_GRPC = "vaultd-grpc"; export type CwtVerificationReason = "invalid_input" | "invalid_token_structure" | "unexpected_algorithm" | "signature_verification_failed" | "invalid_claims" | "issuer_mismatch" | "subject_mismatch" | "audience_mismatch" | "token_expired" | "expiry_mismatch" | "server_identity_expires_before_token"; export declare class CwtVerificationError extends Error { readonly reason: CwtVerificationReason; constructor(message: string, reason: CwtVerificationReason); } export interface VerifyDepositorCwtInput { /** Base64url (no padding) COSE Sign1 token from `auth_createDepositorToken`. */ token: string; /** * VP ephemeral token-signing pubkey (33-byte compressed hex) from the * bundled `server_identity` proof — MUST already be verified by * {@link verifyServerIdentity} before being passed here. */ ephemeralPubkeyHex: string; /** Pinned VP persistent x-only pubkey (on-chain). Asserted against the token `iss`. */ expectedIssuerXOnlyPubkey: string; /** Expected `sub` — {@link CWT_SUBJECT_JSONRPC} or {@link CWT_SUBJECT_GRPC}. */ expectedSubject: string; /** Depositor x-only pubkey. Asserted against the token `aud`. */ expectedAudienceXOnlyPubkey: string; /** Outer wire `expires_at`. Must equal the token's `exp` exactly. */ responseExpiresAt: number; /** `server_identity.expires_at`. Must be ≥ the token's `exp`. */ serverIdentityExpiresAt: number; /** Current Unix time (seconds). Injected for testability. */ now: number; } export interface VerifiedCwtClaims { issuer: string; subject: string; audience: string; expiresAt: number; notBefore: number; issuedAt: number; } /** * Verify a depositor CWT and return its claims, or throw * {@link CwtVerificationError}. * * Steps (mirroring the Rust reference; see the divergence note above): * 1. Decode the COSE Sign1 envelope and assert the protected header * pins ES256K. * 2. Verify the ECDSA signature over the reconstructed Sig_structure * against the (already server-identity-verified) ephemeral key. * 3. Decode the CWT claims and assert `iss`/`sub`/`aud` bindings, the * structural `iat <= exp`, `exp` validity, `cti` presence, and the * outer-vs-inner expiry cross-checks. `nbf`/`iat` are intentionally not * clock-gated here (see the module note above). */ export declare function verifyDepositorCwt(input: VerifyDepositorCwtInput): VerifiedCwtClaims; //# sourceMappingURL=verifyDepositorCwt.d.ts.map