import type { ClientWebvhUpdateKeys } from '../webvh/didWebvh.js'; import type { UserKey } from './userKey.js'; /** * A ceremony's local pending state, decoded: written by a self-enrollment or * recovery-spend ceremony's required persist hook between its reveal-and-commit * entry and its pivot (add / add-and-retire) entry. See the module doc. * * `ceremony` says which ceremony wrote the pending record, so a spend-written * record is never mistaken for a seeded self-enrollment. `builtOnHead` is the * account-log head (SCID plus versionId) the ceremony's pivot entry was built * on, so a resume refuses to rebuild over a served log that has not reached * that head, or that swapped genesis. `unwrapKey` and `replacementCode` belong * to the recovery spend alone: `unwrapKey` carries the spent recovery code's * key-agreement secret so the first post-pivot roster escrow stays * re-derivable, and `replacementCode` carries the once-per-ceremony * replacement recovery code's bytes so a re-run reuses the same unlock Space * address. */ export interface ClientKeyRecordPending { ceremony: 'recovery-spend' | 'self-enrollment'; builtOnHead: { scid: string; versionId: string; }; unwrapKey?: Uint8Array; replacementCode?: Uint8Array; } /** * A client-key record's contents, decoded. * * `clientSeed` is the only always-present member: the rest are absent on * records written before that member existed (a user-key-less account, a record * written before the update keys became client-held, a first client whose own * did:key IS the account controller), or simply not stored by the app. */ export interface ClientKeyRecord { clientSeed: Uint8Array; userKey?: UserKey; webvhUpdateKeys?: ClientWebvhUpdateKeys; controller?: string; pointerDid?: string; pending?: ClientKeyRecordPending; } /** * A client-key record's contents as they are stored: plain JSON, every byte * field base64url-encoded without padding. This is what an app wraps, seals, * or stringifies -- the codec never decides where it goes. */ export interface ClientKeyRecordJson { clientSeed: string; userKey?: { id: string; secret: string; }; webvh?: { updateSeed: string; stagedSeed: string; pendingStagedSeed?: string; }; controller?: string; pointerDid?: string; pending?: { ceremony: 'recovery-spend' | 'self-enrollment'; builtOnHead: { scid: string; versionId: string; }; unwrapKey?: string; replacementCode?: string; }; createdAt?: string; } /** * A record whose every member is present: what an ENROLLED client holds once * the enrollment ceremony has landed (a key set, a delivered user key, its own * update-key seeds, and the account it belongs to). */ export interface EnrolledClientKeyRecord extends ClientKeyRecord { userKey: UserKey; webvhUpdateKeys: ClientWebvhUpdateKeys; controller: string; pointerDid: string; } /** * Parses and validates the optional `userKey` member. An absent member resolves * to `undefined` (a record written for an account minted before the user key); * a present-but-malformed one throws. * * The key-agreement secret is the whole of the stored material: the user key's * Ed25519 signing half derives from it (`userKeySigningSeed`), so it is * neither stored nor read back. * * @param value {unknown} the record's `userKey` member * @returns {UserKey | undefined} */ export declare function parseClientRecordUserKey(value: unknown): UserKey | undefined; /** * Parses and validates the optional `webvh` member: this client's did:webvh * update-key seeds. An absent member resolves to `undefined` (a record written * before the update keys became client-held); a present-but-malformed one * throws. * * @param value {unknown} the record's `webvh` member * @returns {ClientWebvhUpdateKeys | undefined} */ export declare function parseClientRecordWebvhKeys(value: unknown): ClientWebvhUpdateKeys | undefined; /** * Parses and validates the optional `pending` member: a self-enrollment or * recovery-spend ceremony's local pending state. An absent member resolves to * `undefined` (an enrolled record, or a completed ceremony); a * present-but-malformed one throws. * * `unwrapKey` and `replacementCode` belong to the recovery spend alone -- * present under `ceremony: 'self-enrollment'`, either throws. * * @param value {unknown} the record's `pending` member * @returns {ClientKeyRecordPending | undefined} */ export declare function parseClientRecordPending(value: unknown): ClientKeyRecordPending | undefined; /** * Encodes a client-key record's contents for storage: base64url byte fields, * optional members omitted rather than written as null. Every secret is * length-checked on the way out, exactly as the decoder checks it on the way * back in -- an undecodable stored record is a lost account. * * @param options {object} * @param options.clientSeed {Uint8Array} this client's 32-byte seed * @param [options.userKey] {UserKey} the cached user key * @param [options.webvhUpdateKeys] {ClientWebvhUpdateKeys} this client's * did:webvh update-key seeds * @param [options.controller] {string} the account controller this key set * was bound for -- on an enrolled (non-first) client it differs from the * client's own did:key * @param [options.pointerDid] {string} the account's did:webvh * @param [options.pending] {ClientKeyRecordPending} a self-enrollment or * recovery-spend ceremony's local pending state * @param [options.createdAt] {string} when the record was written; defaults * to now * @returns {ClientKeyRecordJson} */ export declare function encodeClientKeyRecord({ clientSeed, userKey, webvhUpdateKeys, controller, pointerDid, pending, createdAt }: { clientSeed: Uint8Array; userKey?: UserKey; webvhUpdateKeys?: ClientWebvhUpdateKeys; controller?: string; pointerDid?: string; pending?: ClientKeyRecordPending; createdAt?: string; }): ClientKeyRecordJson; /** * Decodes and validates a stored client-key record's contents. Throws on any * malformed member -- see the module doc for why nothing here is tolerated * into a degraded record. * * @param options {object} * @param options.contents {unknown} the stored JSON contents (an app that * stores a string parses it first) * @returns {ClientKeyRecord} */ export declare function decodeClientKeyRecord({ contents }: { contents: unknown; }): ClientKeyRecord; /** * Narrows a decoded record to a complete enrolled-client key set, throwing * when any member an enrolled client needs is absent. For an app whose stored * records are only ever written by the enrollment ceremony, this turns "the * codec tolerates older records" into a single checked boundary. * * @param options {object} * @param options.record {ClientKeyRecord} * @returns {EnrolledClientKeyRecord} */ export declare function assertEnrolledClientKeyRecord({ record }: { record: ClientKeyRecord; }): EnrolledClientKeyRecord; /** * The non-throwing twin of {@link assertEnrolledClientKeyRecord}: the same * four-member test (userKey, webvhUpdateKeys, controller, pointerDid all * present), run through that assert so one member list governs both, * deliberately only those four -- a `pending` member does not affect * the result, since the pending discriminator apps route on stays the absence * of `userKey`. Where the assert is a checked boundary that throws naming the * missing member, this guard is for an app that needs to ROUTE on the record's * shape (enrolled / pending / absent) rather than fail on it. * * Takes the record bare (like the per-member parsers above) so the predicate * narrows the caller's own variable. * * @param record {ClientKeyRecord} * @returns {boolean} */ export declare function isEnrolledClientKeyRecord(record: ClientKeyRecord): record is EnrolledClientKeyRecord; //# sourceMappingURL=clientKeyRecord.d.ts.map