/** * handoff-mint.ts, the one place a pairing producer mints a link. * * Every producer (a `pair` CLI block, a pairing modal's QR, a /qrcode flow) * routes through mintPairingHandoff, which mints a fresh per-device token and * encodes the canonical `#pair=` deep link from pairing-handoff.ts, * byte-for-byte the same shape the `pairing.handoff.create` gateway verb's * handler produces (mint + buildPairingHandoffLink). No producer encodes a raw * JSON connection blob: a camera scan of the QR opens the web app already * carrying the one-time token, so the device lands signed in. * * The token rides in the URL fragment, never the query, so it is never sent to a * server (no access-log / Referer exposure). The offer set rides alongside so a * bundle-aware surface can present the notifications/relay/passkey steps. */ import { type PairingHandoffOfferKind } from './pairing-handoff.js'; import { type OriginPosture } from './origin-posture.js'; import type { MintedPairingToken } from './pairing-token-store.js'; /** The token-minting surface a handoff needs, satisfied by {@link PairingTokenManager}. */ export interface PairingTokenMinter { mint(input: { readonly name: string; }): MintedPairingToken; } export interface PairingHandoff { readonly token: MintedPairingToken; readonly offers: readonly PairingHandoffOfferKind[]; /** `#pair=` (with an `offers=` key when offers are present). */ readonly fragment: string; /** `/#pair=`, present only when a web origin is known. */ readonly deepLink?: string | undefined; /** * The honest TLS/capability posture of the web origin the deep link opens, * the same field the `pairing.handoff.create` gateway verb carries (both * computed by describeOriginPosture). Present only when a web origin * is known; a surface renders its one honest LAN line and its labeled * capability list from here, never from a locally-authored string. */ readonly posture?: OriginPosture | undefined; } export interface MintPairingHandoffInput { readonly pairingTokens: PairingTokenMinter; /** The device/token name shown to the user and stored on the token; editable later. */ readonly name: string; readonly offers: readonly PairingHandoffOfferKind[]; /** The web-app origin the deep link points at; absent ⇒ fragment-only. */ readonly webOrigin?: string | undefined; } /** * A default name for a freshly-minted pairing token when the user did not supply * one. Names are shown and editable later in the device management surface, so a * date-stamped default is enough to tell two devices apart at a glance. */ export declare function defaultPairingTokenName(now?: Date): string; export declare function mintPairingHandoff(input: MintPairingHandoffInput): PairingHandoff; /** The link content a QR should encode: the full deep link when known, else the fragment. */ export declare function pairingQrContent(handoff: PairingHandoff): string; export interface PairingOfferAvailability { /** Whether the rendezvous relay is configured ⇒ the relay offer is presentable. */ readonly relayEnabled: boolean; /** Whether a step-up (passkey) ceremony is wired ⇒ the passkey offer is presentable. */ readonly stepUpAvailable: boolean; } /** * The offers this daemon can satisfy right now, in canonical order. Notifications * are always available (browser push needs no server-side prerequisite beyond * the VAPID key the daemon mints on demand); relay and passkey are gated. */ export declare function availablePairingOffers(availability: PairingOfferAvailability): PairingHandoffOfferKind[]; //# sourceMappingURL=handoff-mint.d.ts.map