import { type JsonRpcRequest } from '../transport.js'; export declare const isSecureContextUrl: (value: string) => boolean; /** Options for creating a {@link UrlFlow}. */ export interface UrlFlowOptions { /** The signer's ICRC-167 transport URL. */ url: string; /** The relying party callback URL the signer returns the response to. */ callbackUrl: string; /** Storage used to persist flow progress across the redirect. */ storage: Storage; /** Key under which flow state is stored. */ storageKey: string; /** * Time in milliseconds after which an unfinished flow's persisted state is * considered stale and ignored (a new flow starts instead). */ flowTimeout: number; /** Location used to read the callback and perform the redirect. */ location: Pick; /** History used to strip the fragment after reading a response. */ history: Pick; /** Source of random UUIDs for the `state` parameter. */ crypto: Pick; /** Clock used to timestamp flow state and expire it. */ now: () => number; } /** * The shared journal for one URL-transport flow (one page load). * * A single call-order-keyed record of results is shared by memoized steps and * signer requests, and persisted across the top-level redirect. Concurrently * issued requests are coalesced into one JSON-RPC batch and one redirect. * * A load continues an existing flow only when it is a signer **return** — the * URL carries a `message` matching the stored `pending`. In that case the * returned responses are folded into the journal and the calling code replays * from it (already-completed calls resolve from storage instead of navigating * again). Any other load — a bare visit to the callback, a leftover completed * journal, or an abandoned `pending` with no `message` — starts a **fresh** * flow: the stored journal is ignored and overwritten by the first request. So * navigating to the callback always starts the flow, and there is no separate * "clear" step — a finished flow's journal is simply inert to the next one. * (`flowTimeout` is a backstop for the storage entry.) */ export declare class UrlFlow { #private; constructor(options: UrlFlowOptions); /** Reserves the next call-order slot. */ next(): number; /** * The stored result for a slot, or `undefined` if it has not completed. * @param index - The call-order slot to read. */ get(index: number): unknown; /** * The content fingerprint recorded for a request slot, or `undefined` if no * request was journaled there. Used by the channel's replay divergence guard. * @param index - The call-order slot to read. */ recordedRequestKey(index: number): string | undefined; /** * Buffers an uncached request for the next redirect. * @param index - The call-order slot reserved for the request. * @param request - The JSON-RPC request to send on the next redirect. * @param key - Content fingerprint recorded for the divergence guard. */ request(index: number, request: JsonRpcRequest, key: string): void; /** * The core journaled step: runs `produce` once for its call-order slot and * records the result, or returns the recorded result on a replay load * without running `produce` again. This is what `UrlTransport.memoize` * exposes for any async work other than a signer request (e.g. fetching a * single-use nonce), and it shares its call-order counter with requests. * @param produce - Produces the value on the first load; awaited if a promise. * @returns The produced value, or the journaled value on a replay load. */ memoize(produce: () => Promise): Promise; memoize(produce: () => T): T; }