/*! * Copyright (c) 2026 Interop Alliance. All rights reserved. */ /** * Seed persistence: the master seed at rest in the app's own IndexedDB, so a * reload restores the session with zero wallet popups. A raw-IndexedDB pattern * (one db, one object store, fixed record keys, `db.close()` after every * operation). Wiped on logout. * * `createSeedStore` binds a database name (each app supplies its own) and an * optional `idb` factory (injectable for tests, e.g. fake-indexeddb), returning * the five bound operations. * * {@link createDescriptorCache} presents the descriptor record of one such * store as the `EncryptionDescriptorCache` seam * (`@interop/wallet-core/descriptors`), which is what the session's * descriptor acquisition reads and writes through. It adds two BULK operations * on top of that seam ({@link SessionDescriptorCache}): the whole cache in one * read, and a whole set of descriptors in one read-modify-write. A session * bring-up phase reads or writes every registered collection at once, so the * bulk pair costs one IndexedDB open/close per phase instead of one per * collection. */ import type { CollectionEncryption } from '@interop/was-client'; import type { EncryptionDescriptorCache } from '@interop/wallet-core/descriptors'; /** * The bound seed-store operations returned by `createSeedStore`. */ export interface SeedStore { /** * Persists the 32-byte master seed. */ saveSeed(seed: Uint8Array): Promise; /** * Loads the persisted master seed, or `null`. */ loadSeed(): Promise; /** * Persists an opaque session record (see `appSession.ts`). */ saveRecord(record: unknown): Promise; /** * Loads the persisted session record, or `null`. */ loadRecord(): Promise; /** * Persists the collection-encryption descriptor cache (descriptors keyed by * WAS collection id, stamped with the controller DID they belong to), so an * offline / hot-restore session can rebuild its epoch-aware ciphers without * a live description read. */ saveDescriptors(descriptors: unknown): Promise; /** * Loads the persisted descriptor cache, or `null`. */ loadDescriptors(): Promise; /** * Wipes the seed, the session record, and the descriptor cache (logout). */ clearSeedStore(): Promise; } /** * Creates a seed store bound to `dbName` and `idb`. * * @param options {object} * @param options.dbName {string} the IndexedDB database name * @param [options.idb] {IDBFactory} the IndexedDB factory (defaults to the * global `indexedDB`; inject a fake for tests) * @returns {SeedStore} */ export declare function createSeedStore({ dbName, idb }: { dbName: string; idb?: IDBFactory; }): SeedStore; /** * The session's descriptor cache: the `EncryptionDescriptorCache` seam * `@interop/wallet-core/descriptors` acquires through, plus the two bulk * operations a session bring-up works in. Every op reads (or read-modify-writes) * the same single stored blob, so doing a whole phase at once costs one * IndexedDB open/close rather than one per collection. */ export interface SessionDescriptorCache extends EncryptionDescriptorCache { /** * Reads the whole cached set (by WAS collection id) in one blob read. Empty * when nothing is cached, or when the blob belongs to another controller. */ readAllDescriptors(): Promise>; /** * Merges a whole set of descriptors into the cache in ONE serialized * read-modify-write, on the same write chain `writeDescriptor` rides (so the * two can never lose one another's entries). Entries not named here are left * as they are. * * @param options {object} * @param options.descriptors {Record} * @returns {Promise} */ writeDescriptors(options: { descriptors: Record; }): Promise; } /** * Presents a {@link SeedStore}'s persisted descriptor record as the * `EncryptionDescriptorCache` seam that `@interop/wallet-core/descriptors` * acquires through: per-collection get/put over the single stored blob, already * scoped to one session's Space by the store it is bound to. * * The blob is stamped with the `controller` DID whose descriptors it holds, and * a cache bound to a different controller reads it as empty (and overwrites the * stamp on its first write). Descriptors name key-epoch rosters a specific * identity is a recipient of, so a login under a different controller than the * one that cached them must never trust them: a stale hit would build ciphers * the new identity cannot unwrap. * * The blob is read-modify-written on every put. That is fine at this scale (an * app registers a handful of collections) and it is the only shape the existing * one-record persistence allows; concurrent puts are serialized through a * promise chain so two of them cannot lose one another's entry. * * The returned cache is a superset of the seam * ({@link SessionDescriptorCache}): `readAllDescriptors` and `writeDescriptors` * do a whole bring-up phase in one blob read, or one read-modify-write, * instead of one IndexedDB open/close per collection. * * @param options {object} * @param options.store {SeedStore} the session seed store to persist through * @param options.controller {string} the controller DID the cached * descriptors belong to * @returns {SessionDescriptorCache} */ export declare function createDescriptorCache({ store, controller }: { store: SeedStore; controller: string; }): SessionDescriptorCache; //# sourceMappingURL=seedStore.d.ts.map