import { P as PeerIndex, C as CipherSuite } from '../ratchet-crypto-Bu7ZATDd.js'; /** Context passed to seal/unseal identifying the room and sender. */ interface MlsSealContext { roomId: string; senderUid: string; } /** Epoch material delivered to the provider via setEpoch. */ interface MlsEpochParams { /** MLS epoch number (from ts-mls groupContext.epoch). */ epoch: number; /** peerId → peerIndex map for this epoch (lex-sorted, §7.8-valid). */ peerIndexMap: Record; /** MLS ChainKey (suite.chainKeyBytes long) derived via mlsExporter. */ chainKey: Uint8Array; } /** Options for createMlsChatProvider. */ interface MlsChatProviderOptions { /** * SFrame cipher suite — determines chainKeyBytes (32 or 64) and HKDF hash. * MUST match the MLS group's ciphersuite. Default 'AES_128_GCM_SHA256'. */ suite?: CipherSuite; /** * CTR allocation strategy. Same semantics as createChatProvider. * Default 'random-64'. */ ctrStrategy?: 'random-64' | 'monotonic-idb'; /** Required when ctrStrategy is 'monotonic-idb'. Namespaces the IDB store. */ ctrKeyspace?: string; /** * In-memory replay window size (per sender per room). Default 1024. * 0 disables replay protection (debug only). */ replayWindow?: number; /** * Durable cross-reload replay protection (CWE-294). Same semantics as * createChatProvider. Default ON when a namespace is provided. */ durableReplay?: boolean; /** Namespace for the durable replay IDB store. */ durableReplayNamespace?: string; /** Durable replay window size. Default equals replayWindow. */ durableReplayWindow?: number; /** * Maps a senderUid (from SealContext) to a peerId in the peerIndexMap. * The default uses the senderUid directly — override if your peerIds * differ from senderUids (e.g. base64-encoded MLS credentials). */ uidToPeerId?: (senderUid: string) => string; /** Called synchronously when clearEpoch(roomId) is invoked. */ onEpochCleared?: (roomId: string) => void; } /** The provider returned by createMlsChatProvider. */ interface MlsChatProvider { /** * Install epoch material for a room. Called after each MLS epoch advance * (createGroup, joinGroup, processMessage on commit). Derives per-sender * SFrameKeys from the ChainKey and caches them. * * The ChainKey is zeroized after derivation — the caller's copy is not * touched. */ setEpoch(roomId: string, params: MlsEpochParams): Promise; /** * Encrypt plaintext for the given (roomId, senderUid). The sender MUST be * a member of the current epoch's peerIndexMap. Throws if no epoch has * been installed for the room or the sender is not in the map. */ seal(plaintext: Uint8Array, ctx: MlsSealContext): Promise; /** * Decrypt an SFrame buffer. Validates AEAD, checks replay window. * Throws ReplayError on replay; AEADAuthError on key/uid/room mismatch. */ unseal(sealed: Uint8Array, ctx: MlsSealContext): Promise; /** * Clear epoch state + replay windows for a room. Called when leaving a * room or on full state reset. Does NOT clear CTR allocator state. */ clearEpoch(roomId: string): void; /** Current epoch number for a room, or null if none installed. */ getEpoch(roomId: string): number | null; /** Release all resources. */ dispose(): void; } /** * Create an MLS-backed chat-mode SFrame provider. * * The provider is stateful (per-room epoch state, replay windows). Create one * instance per application lifetime. The caller drives MLS group lifecycle * via ts-mls and calls setEpoch after each epoch advance. * * @example * ```ts * const provider = createMlsChatProvider({ suite: 'AES_128_GCM_SHA256' }); * // After MLS epoch advance: * await provider.setEpoch(roomId, { epoch, peerIndexMap, chainKey }); * const sealed = await provider.seal(plaintext, { roomId, senderUid }); * const plain = await provider.unseal(sealed, { roomId, senderUid }); * ``` */ declare function createMlsChatProvider(opts?: MlsChatProviderOptions): MlsChatProvider; export { type MlsChatProvider, type MlsChatProviderOptions, type MlsEpochParams, type MlsSealContext, createMlsChatProvider };