/** * Crossdeck Trust — the human-proof panel, native to the SDK. * * This is the browser half of Crossdeck Trust wired THROUGH the SDK the customer * already runs, not bolted on beside it. It renders the SAME cross-origin iframe * served from trust.cross-deck.com — the un-restylable, browser-enforced brand * panel — and hands the minted attestation back PROGRAMMATICALLY (a Promise + an * `onToken` callback) instead of the hidden-field/DOM handshake the raw * `embed.js` loader uses. The iframe is the bouncer; the SDK is the premium front * door to it. You pass the token to your server, which verifies it at the gate * (`crossdeck.trust.gate(...)` in @cross-deck/node, or a raw POST /v1/trust/gate). * * Non-negotiables baked in (Stripe / Cloudflare / bank grade): * - ISOLATED — every DOM / postMessage touch is wrapped; a stumble here can never * throw into the host app, the rest of the SDK, or the customer's signup form. * - FAIL-OPEN, never fail-allow — if the panel can't mint (adblocker, our outage, * offline, timeout), `ready` resolves with NO token. The signup proceeds; the * SERVER gate scores the ABSENCE. We never wave a tokenless request through, and * we never block the form because our panel had a bad day. Failing CLOSED would * hand an attacker a site-wide-outage weapon — so we never do. * - ORIGIN-LOCKED — we only trust messages from OUR panel origin AND from this * exact iframe's window. Nothing on the host page can forge a token. * - The token is minted INSIDE our origin; the host page (even an XSS on it) never * participates in the mint, it only receives the finished token. */ /** The origin that serves the branded, un-restylable Trust panel. */ declare const TRUST_PANEL_ORIGIN = "https://trust.cross-deck.com"; /** A minted human-proof attestation. Pass `token` to your gate call. */ interface TrustToken { /** The single-use, project-bound attestation to send to your server as `token`. */ token: string; /** Epoch ms at which the token expires (mint fresh per signup attempt), or null. */ expiresAt: number | null; } /** Resolution of a panel that failed open — a token never minted. Not an error. */ interface TrustUnavailable { token: null; expiresAt: null; /** Why no token was minted (for your logs) — e.g. "timeout", "blocked", "offline". */ reason: string; } type TrustResult = TrustToken | TrustUnavailable; /** Lifecycle of a panel driven by a framework binding: pending → ready | unavailable. */ type TrustTokenStatus = "pending" | "ready" | "unavailable"; interface MountTrustPanelOptions { /** The project's publishable key (cd_pub_…). The SDK client supplies this for you. */ publicKey: string; /** Where to render the panel — an element or a selector resolved at mount time. */ target: HTMLElement | string; /** Called once when a token is minted. Optional — you can await `ready` instead. */ onToken?: (t: TrustToken) => void; /** * Called if the panel could not mint (blocked, offline, timeout, our outage). * INFORMATIONAL for your logs — NOT an error you must handle: `ready` still * resolves and your signup proceeds. Fail-open is the contract. */ onUnavailable?: (reason: string) => void; /** Override the panel origin (tests / self-host). Defaults to production. */ origin?: string; /** Max wait for a mint before failing open, in ms. Default 15000. */ timeoutMs?: number; } interface TrustPanelHandle { /** The iframe we mounted — for layout/measurement only; never reach inside it. */ readonly frame: HTMLIFrameElement | null; /** * Resolves EXACTLY once: the token on success, or a {@link TrustUnavailable} if * the panel failed open. NEVER rejects — a rejection would tempt callers to block * the signup, which is precisely what fail-open forbids. */ readonly ready: Promise; /** Tear down: remove the iframe + listeners. Idempotent. */ destroy(): void; } /** * Options for `Crossdeck.trust.panel(...)` — the same as {@link MountTrustPanelOptions} * but the SDK client injects `publicKey` from your `init()`, so you omit it. */ type TrustPanelInput = Omit & { /** * The project's publishable key (cd_pub_…). Pass it **explicitly** — the robust, * Stripe (`loadStripe(pk)`) / Cloudflare Turnstile (`sitekey`) pattern — and the * panel needs no `Crossdeck.init()` at all. Omit it and the SDK falls back to the * key from `init()`. Explicit always wins. */ publicKey?: string; }; /** The `Crossdeck.trust` namespace surfaced on the SDK client. */ interface CrossdeckTrustNamespace { /** Render the branded Trust panel and mint an attestation. See {@link mountTrustPanel}. */ panel(input: TrustPanelInput): TrustPanelHandle; } /** * Mount the Crossdeck Trust panel and mint an attestation. Framework-agnostic and * guaranteed not to throw — any construction failure resolves `ready` fail-open. */ declare function mountTrustPanel(opts: MountTrustPanelOptions): TrustPanelHandle; export { type CrossdeckTrustNamespace as C, type MountTrustPanelOptions as M, type TrustToken as T, type TrustTokenStatus as a, TRUST_PANEL_ORIGIN as b, type TrustPanelHandle as c, type TrustPanelInput as d, type TrustResult as e, type TrustUnavailable as f, mountTrustPanel as m };