import { Cigar, Diger, Salter, Siger, Signer, type Tier, Verfer } from "../../../cesr/mod.js"; import { Keeper } from "../db/keeping.js"; /** * Root key-creation strategy selectors stored in keeper globals. * * `randy` and `salty` are implemented in the current TS port. The others are * preserved so the app-layer contract stays aligned with KERIpy naming. */ export declare enum Algos { randy = "randy", salty = "salty", group = "group", extern = "extern" } /** * Inputs for constructing a `Manager` over an already-open `Keeper`. * * The manager persists most root state in `ks.gbls`; `seed` remains * process-local so readonly/inspection opens can avoid writing secrets back to * disk. */ export interface ManagerArgs { ks: Keeper; seed?: string; aeid?: string; pidx?: number; algo?: Algos; salt?: string; tier?: Tier; } /** * Controls key-material derivation for `Manager.incept()`. * * This is the TypeScript option-object surface corresponding to KERIpy's * richer incept contract: enough for the implemented `randy`/`salty` creator * paths across the supported signing suites, but not yet the full keeper * algorithm matrix. */ export interface ManagerInceptArgs { icodes?: string[]; icount?: number; ncodes?: string[]; ncount?: number; icode?: string; ncode?: string; dcode?: string; algo?: Algos; salt?: string; stem?: string; tier?: Tier; rooted?: boolean; transferable?: boolean; temp?: boolean; } /** Controls one managed-prefix rotation using the stored keeper policy for `pre`. */ export interface ManagerRotateArgs { pre: string; ncodes?: string[]; ncount?: number; ncode?: string; dcode?: string; transferable?: boolean; temp?: boolean; erase?: boolean; } /** * Manager-level key-lot address metadata inferred from KERIpy's documented * `Manager.sign(..., pre=..., path=...)` intent. * * This is not a raw salty derivation path string. It is the tuple part * `(ridx, kidx)` used to identify one key list inside one managed prefix: * - `ridx` is the optional rotation index of the establishment event that uses * the addressed public-key set * - `kidx` is the required zeroth key index of that key list in the full key * sequence * * The manager uses `pre` to look up keeper state and, for `salty`, reconstructs * the fully derived signer paths from the stored stem/pidx plus this metadata. */ export interface SigningPath { ridx?: number; kidx: number; } /** * Inputs for `Manager.sign(...)`. * * Resolution precedence matches KERIpy intent: * - explicit `pubs` * - explicit `verfers` * - managed `pre/path` */ export interface ManagerSignArgs { pubs?: string[]; verfers?: Verfer[]; indexed?: boolean; indices?: number[]; ondices?: Array; pre?: string; path?: SigningPath; } /** Decrypt through managed private keys resolved from explicit publics/verfers. */ export interface ManagerDecryptArgs { pubs?: string[]; verfers?: Verfer[]; } /** * Import externally generated key material into keeper state. * * KERIpy correspondence: * - `secrecies` is an ordered list of ordered secret lists, one establishment * event at a time * - the manager records those lists as historical/current key lots, then * creates one fresh `nxt` lot that follows the imported sequence */ export interface ManagerIngestArgs { secrecies: string[][]; iridx?: number; ncount?: number; ncode?: string; dcode?: string; algo?: Algos; salt?: string; stem?: string; tier?: Tier; rooted?: boolean; transferable?: boolean; temp?: boolean; } /** Replay one persisted managed key sequence forward from keeper state. */ export interface ManagerReplayArgs { pre: string; dcode?: string; advance?: boolean; erase?: boolean; } /** Common creator input contract for both random and deterministic key factories. */ export interface CreatorCreateArgs { codes?: string[]; count?: number; code?: string; pidx?: number; ridx?: number; kidx?: number; transferable?: boolean; temp?: boolean; } /** Small keeper-facing bundle pairing one signer with its already-derived verifier. */ interface SignerMaterial { signer: Signer; verfer: Verfer; } /** * Derive a deterministic Ed25519 signer pair from salty root material. * * KERIpy correspondence: * - mirrors the current salty derivation path used by `Manager` for root and * per-prefix key material * * Current `keri-ts` difference: * - returns the narrow CESR primitives directly so callers can decide whether * to keep semantic objects or project `.qb64` at the boundary they need */ export declare function saltySigner(saltQb64: string, path: string, transferable: boolean, tier: Tier, temp: boolean): SignerMaterial; /** Base key-creation strategy seam mirrored from KERIpy's creator hierarchy. */ export declare class Creator { /** Create one signer list according to the concrete creator policy. */ create(_args?: CreatorCreateArgs): Signer[]; /** Deterministic root salt used by salty creators; empty for non-salty families. */ get salt(): string; /** Path stem prefix used by salty creators; empty for non-salty families. */ get stem(): string; /** Default derivation tier carried by the concrete creator policy. */ get tier(): Tier; } /** Random signer creator that makes one fresh seed per requested suite. */ export declare class RandyCreator extends Creator { create({ codes, count, code, transferable, }?: CreatorCreateArgs): Signer[]; } /** Deterministic salty creator that derives signers from one salt and path policy. */ export declare class SaltyCreator extends Creator { readonly salter: Salter; private readonly _stem; constructor({ salt, stem, tier }?: { salt?: string; stem?: string; tier?: Tier; }); get salt(): string; get stem(): string; get tier(): Tier; create({ codes, count, code, pidx, ridx, kidx, transferable, temp, }?: CreatorCreateArgs): Signer[]; } /** Creator factory mirrored from KERIpy's `Creatory`. */ export declare class Creatory { private readonly algo; constructor(algo?: Algos); /** Materialize the configured creator family with its optional salt/stem policy. */ make({ salt, stem, tier }?: { salt?: string; stem?: string; tier?: Tier; }): Creator; } /** * Key-management coordinator backed by `Keeper` state. * * Responsibilities: * - own keeper-global root settings (`aeid`, `pidx`, `algo`, `salt`, `tier`) * - derive incept/current/next key material * - persist per-prefix parameters, situations, and public-key sets * * KERIpy correspondence: * - mirrors the role of `keri.app.keeping.Manager` * * Current `keri-ts` differences: * - `randy` and `salty` creator algorithms are live; `group` and `extern` * remain explicit unsupported-algorithm seams * - AEID handling now includes real sealed-box encryption for keeper-global * salt, per-prefix salts, and signer seeds, while keeping the encrypted * runtime dependency local to the KERI package instead of CESR * - readonly opens intentionally avoid keeper mutation so visibility commands * can inspect stores without side effects */ export declare class Manager { private _seed; private _ks; /** Public box key derived from AEID; used only when writing encrypted secrets. */ private encrypter; /** Private box key derived from passcode/seed; required for encrypted reads. */ private decrypter; constructor(args: ManagerArgs); get ks(): Keeper; /** Process-local AEID/authentication seed kept only in memory, never persisted in keeper state. */ get seed(): string; /** Stored non-transferable auth/encryption identifier prefix from keeper globals. */ get aeid(): string; /** Next prefix index for a new managed key sequence, stored in hex text in `gbls.`. */ get pidx(): number | null; /** Persist the next managed-prefix index in keeper-global hex form. */ set pidx(pidx: number); /** Keeper-global default creator algorithm for newly rooted managed sequences. */ get algo(): Algos | null; /** Persist the keeper-global default creator algorithm. */ set algo(algo: Algos); /** * Keeper-global root salt. * * Storage invariant: * - plaintext qb64 when no AEID encryption is active * - `X25519_Cipher_Salt` qb64 when a decrypter/encrypter pair is active * * Caller contract: * - callers always see canonical plaintext salt qb64 from this getter * - the encrypted/plain distinction is strictly an at-rest concern */ get salt(): string | null; set salt(salt: string); get tier(): Tier | null; /** Persist the keeper-global default stretch tier for rooted salty derivation. */ set tier(tier: Tier); /** * Initialize or reopen manager encryption state against the underlying keeper. * * Reopen rules: * - if the keeper has never stored an AEID, first-time initialization may set * one unless the keeper is readonly * - if the keeper already has an AEID, the caller must supply a seed/passcode * that proves possession of the matching decrypt key * - readonly opens never rewrite keeper globals, even when the caller also * provides AEID input * * Maintainer warning: * This is the place where "seed means process-local input" meets * "AEID means persistent keeper policy". Be careful not to collapse those two * concepts or readonly visibility commands will start mutating stores again. */ setup(aeid?: string, seed?: string): void; /** * Change keeper AEID policy and re-encrypt every affected secret in place. * * Re-encryption scope: * - keeper-global root salt in `gbls.salt` * - per-prefix salts in `prms.salt` * - signer seeds in `pris.` * * Behavior matrix: * - `current AEID -> same AEID`: validate and keep stable * - `current AEID -> new AEID`: decrypt with old seed, re-encrypt with new * public box key * - `current AEID -> empty`: decrypt and persist plaintext secrets * - `empty -> new AEID`: encrypt newly managed secrets going forward * * Failure model: * - current seed must authenticate the currently stored AEID before any * secret migration is attempted * - new seed must authenticate the new AEID before any re-encryption is * attempted */ updateAeid(aeid: string, seed: string): void; private signerDecrypter; /** Load one managed signer seed by its public verifier key. */ private getSignerByPub; /** Resolve signers from either explicit public-key text or hydrated verifiers. */ private getSigners; /** Resolve one known current/next/old lot directly from the live `PreSit` projection. */ private knownSigningLot; /** * Resolve manager-level `(ridx, kidx)` addressing into one concrete pub lot. * * Resolution order: * - prefer the live `old/new/nxt` lots already carried in `PreSit` * - otherwise fall back to historical `pubs.` storage for replay-style lots */ private resolveSigningPath; /** Select and order the addressed public keys according to optional `indices`. */ private selectSigningKeys; /** * Reconstruct signer material for one salty-managed key lot. * * Maintainer rule: * - derive from persisted keeper parameters, not from stored signer secrets * - validate every derived signer against the stored pub before using it */ private deriveSaltySigningSigners; /** * Normalize one signing request into the concrete signer list that will emit signatures. * * Branch precedence intentionally follows KERIpy: * - explicit `pubs` * - explicit `verfers` * - managed `pre/path` addressing */ private resolveSigningRequest; /** Decrypt one persisted per-prefix salt through the current keeper policy. */ private decryptPreSalt; /** * Create current and next key material for one new managed prefix. * * Keeper-state parity: * - `ps.nxt.pubs` now stores next public keys, not next digests * - returned digers are derived from those stored next public keys on demand * * Rooting/default rules: * - rooted inception inherits missing `algo`, `salt`, and `tier` from * keeper globals * - unrooted inception falls back only to local per-call defaults * * Transferability rule: * - an empty next-key set (`ncount=0` / empty `ncodes`) makes the managed * sequence effectively non-rotatable even if the current prefix material * is otherwise transferable */ incept(args?: ManagerInceptArgs): [Verfer[], Diger[]]; /** * Rebind one temporary/default prefix keyspace to its final derived prefix. * * KERIpy correspondence: * - this is the `Manager.move()` / `repre`-style keeper operation used once * the real identifier prefix is known and the temporary inception key needs * to stop being the durable lookup key */ move(oldPre: string, newPre: string): void; /** * Advance one managed prefix from its current `nxt` lot to a new future `nxt` lot. * * Returns: * - current verfers for the newly active key set * - digers for the freshly derived next public-key lot * * Edge-case rules: * - an empty current `nxt` lot means the managed prefix is effectively * non-transferable and may not rotate further * - `erase=true` removes only the stale `old` signer seeds after the durable * state update succeeds */ rotate(args: ManagerRotateArgs): [Verfer[], Diger[]]; /** * Sign through either explicit stored signers (`pubs` / `verfers`) or one * managed keeper prefix (`pre` plus optional key-list path metadata). * * KERIpy parity note: * - the `pre/path` branch is inferred from KERIpy's documented `Manager.sign` * intent because upstream left that branch stubbed * - `path` is not a raw salty derivation string; it identifies one key list by * `(ridx, kidx)` so the manager can resolve or reconstruct the correct signers * * Maintainer warning: * - derived salty signing depends only on persisted keeper parameters * - temporary stretch mode (`temp=true`) is taken from the active keeper so * path signing can rederive keys created by temp test stores * * Signature-index semantics adapted from KERIpy: * - explicit `pubs` / `verfers` keep the usual coherent-list behavior: * `indices` set each returned `Siger.index`, and `ondices` set each * returned `Siger.ondex` * - derived `pre/path` signing adds one more meaning hinted at by KERIpy's * stubbed branch: `indices` also select offsets from the addressed key lot, * in caller order, before those same values are emitted as `Siger.index` * - when `path` is omitted, the addressed key lot defaults to the current * `.new` lot for `pre` */ sign(ser: Uint8Array, pubs: string[], indexed: true): Siger[]; sign(ser: Uint8Array, pubs: string[], indexed?: false): Cigar[]; sign(ser: Uint8Array, args: ManagerSignArgs & { indexed: true; }): Siger[]; sign(ser: Uint8Array, args?: ManagerSignArgs): Siger[] | Cigar[]; /** * Decrypt one sealed-box qb64 payload through explicit stored signer seeds. * * KERIpy correspondence: * - this is the explicit `pubs` / `verfers` decrypt path * - unlike signing, there is no derived `pre/path` branch here in the * current port * * The resolved Ed25519 signer seeds are converted to their matching X25519 * private box keys inside `Decrypter`. */ decrypt(qb64: string | Uint8Array, args?: ManagerDecryptArgs): Uint8Array; /** * Register externally generated key sequences into keeper state. * * KERIpy correspondence: * - `secrecies` is ordered in establishment-event order * - the imported sequence becomes historical/current lots * - one new future lot is then created from the configured creator policy * - imported secrets are kept; unlike `rotate()`, ingest does not erase * prior signer material * * Returns: * - `ipre`: the initial prefix lookup key for later replay/move operations * - `verferies`: verifier lists mirroring the ingested secrecy lists * * `iridx` rule: * - records before `iridx` become replay history * - the lot at `iridx` becomes current `.new` * - the next lot becomes `.nxt`, or a freshly derived lot if ingestion ends * first */ ingest(args: ManagerIngestArgs): [string, Verfer[][]]; /** * Replay one persisted managed key sequence from keeper state. * * Returns the current verfer list and the next digers for the replayed * position, optionally advancing durable `PreSit` state one step. * * End-of-sequence rule: * - `advance=true` raises `RangeError` once replay reaches a point where no * later `pubs.` lot exists to become the next future set */ replay(args: ManagerReplayArgs): [Verfer[], Diger[]]; } /** * Normalize caller-provided salt material or synthesize a new random salt. * * Provided salts are parsed and re-emitted through `Salter` so the returned * qb64 always uses canonical KERI salt encoding. */ export declare function normalizeSaltQb64(salt?: string): string; /** Convert a 21-char passcode seed slice into KERI's 128-bit salt qb64 text. */ export declare function branToSaltQb64(bran: string): string; /** Encode one v1 counter token directly when higher layers already know code/count. */ export declare function encodeCounterV1(code: string, count: number): string; /** Encode one large ordinal through the CESR Huge-number primitive family. */ export declare function encodeHugeNumber(num: number): string; /** Rehydrate one qb64 text token through the primitive layer to normalize its effective code. */ export declare function normalizeQb64Code(qb64: string): string; /** Build a Blake3-256 SAID directly from raw bytes for local record helpers. */ export declare function makeSaider(raw: Uint8Array): string; /** Decode URL-safe base64 text using the CESR byte helper semantics. */ export declare function b64DecodeUrl(text: string): Uint8Array; /** * Backward-compatibility no-op for older app-layer startup seams. * * CESR primitives now own libsodium readiness through their own module * initialization, so higher layers no longer need an explicit keeper-crypto * readiness step. */ export declare function ensureKeeperCryptoReady(): void; export {}; //# sourceMappingURL=keeping.d.ts.map