import type { DIDDoc, DIDLog, ServiceEndpoint, VerificationMethod } from '@interop/did-method-webvh'; import type { WebvhIdStore } from '../webvh/didWebvh.js'; import type { RelationMembership } from '../webvh/mergeMethods.js'; /** * What the add-and-retire entry retired, read back OFF THE LOG -- the resumed * spend's answer to the same question the live run answers from the document * it is editing. A run torn after that entry but before the caller's registry * and unlock-Space teardown resumes into the already-complete branch, and * without this it would be told nothing was retired and leave every other * credential's registry entry standing. * * The entry is located by its own signature on the log: it is the first entry * whose effective `updateKeys` authorize the successor key (the fresh * ladder's rung 0 on the transient continuation, the new client's update key * on the remembered one), which only that entry writes. What it retired is * then the credential-class `keyAgreement` ids its predecessor published and * it does not, less the spent code's own id -- the same exclusion the live * branch makes, since the caller retires that one by name. * * @param options {object} * @param options.log {DIDLog} the verified account log * @param options.did {string} the account DID the log resolves to * @param options.successorKeyMultibase {string} the update key only the * add-and-retire entry authorizes * @param options.spentVmId {string} the spent code's key-agreement * verification-method id, excluded from the result * @returns {string[]} the retired credentials' key-agreement ids, empty * when no entry authorizes the successor key or it is the genesis entry */ export declare function retiredCredentialVmIdsFromLog({ log, did, successorKeyMultibase, spentVmId }: { log: DIDLog; did: string; successorKeyMultibase: string; spentVmId: string; }): string[]; /** * What a recovery spend retired, the three members both continuations * report: the credential-class `keyAgreement` ids the add-and-retire entry * struck for pre-recovery credentials OTHER than the spent code (what a * caller drops registry entries and deletes unlock Spaces for), the rung * hashes the entry struck, and the retired credentials whose rungs the log * could not attribute -- each of which keeps a committed rung it could still * reveal, and is left for the caller to report rather than struck. */ export interface RecoverySpendRetirement { retiredCredentialVmIds: string[]; struckRungHashes: string[]; unclaimedCredentialVmIds: string[]; } /** * The retirement report of a spend whose add-and-retire entry already * stands, read back off the log: the same three members the continuation * returns, derived the way its completed branch derives them, so a resume * that holds only the successor's public halves (a remembered spend's pending * client-key record, say) reports exactly what the first run reported rather * than a second definition of the same question. * * The entry is located by the successor key it authorized * ({@link retiredCredentialVmIdsFromLog}), and the strike is recomputed over * the log as it stood just before that entry with the same protected sets the * first run used: the successor key and its staged partner, and the * replacement code's rung 0. A log that does not authorize the successor key * (the entry never landed) reports nothing retired, since there is no entry to * read back. * * @param options {object} * @param options.log {DIDLog} the verified account log * @param options.did {string} the account DID the log resolves to * @param options.successor {object} the public halves of the key the entry * authorized (`updateKeyMultibase`) and the staged partner whose hash the * reveal entry committed after it (`stagedKeyMultibase`) * @param options.replacementUpdateKeyMultibase {string} the replacement * code's rung-0 update key * @param options.spentKeyAgreementKeyMultibase {string} the spent code's * key-agreement key, excluded from the retired set * @returns {Promise} */ export declare function recoverySpendRetirementFromLog({ log, did, successor, replacementUpdateKeyMultibase, spentKeyAgreementKeyMultibase }: { log: DIDLog; did: string; successor: { updateKeyMultibase: string; stagedKeyMultibase: string; }; replacementUpdateKeyMultibase: string; spentKeyAgreementKeyMultibase: string; }): Promise; /** * The verification-method id a code's key-agreement key publishes under -- * the ordinary `#` form, indistinguishable by id from any * other keyAgreement entry. Consumers that must exclude recovery entries do * it structurally (an enrolled client is a `capabilityInvocation` entry; a * recovery key never has one) or by the registry's recorded multibase. * * @param options {object} * @param options.did {string} the account's did:webvh * @param options.keyAgreementKeyMultibase {string} * @returns {string} */ export declare function recoveryVmId({ did, keyAgreementKeyMultibase }: { did: string; keyAgreementKeyMultibase: string; }): string; /** * The public halves of a recovery code as the document and log carry them: * the X25519 key-agreement key published as the recovery VM, and the update * key whose hash stands in `nextKeyHashes`. */ export interface RecoveryPublicKeys { keyAgreementKeyMultibase: string; updateKeyMultibase: string; } /** * The public halves a SPEND needs of the replacement code it publishes: the * two above plus the code's ladder VM key, which the add-and-retire entry * installs under `assertionMethod` and `capabilityDelegation`. A code is a * standing unlock credential with a ladder (`decisions/0020`) and its bridge * delegation is signed by that ladder's VM (`decisions/0019`), so a * replacement published without the VM could neither sign its own bridge nor * spend. `recoveryClientFromCode` produces all three. */ export interface ReplacementRecoveryPublicKeys extends RecoveryPublicKeys { ladderVmKeyMultibase: string; } /** * Thrown by the recovery continuation when the log carries neither the code's * update key nor its committed hash -- the code was revoked (or never * issued), so no continuation can verify. */ export declare class RecoveryKeyNotCommittedError extends Error { constructor(message?: string); } /** * Thrown by the recovery continuation, before its reveal entry, when a * credential-class `keyAgreement` id the add-and-retire entry would introduce * already stands in the document -- the user re-typed a passphrase the * account already stands on. The recovery exists to retire that credential, * and an entry that re-binds it would strike its old ladder VM while leaving * its old rung commitments standing, one member backed by two ladders. The * app maps the refusal to "choose a passphrase you have not used". Nothing * is published. */ export declare class RecoveryCredentialStandingError extends Error { readonly credentialVmIds: string[]; constructor({ credentialVmIds }: { credentialVmIds: string[]; }); } /** * The narrow store seam the recovery continuation writes through: a public * read of the log and the delegated `did.jsonl` PUT. A subset of * {@link WebvhIdStore}, so an app's remote-store class satisfies it too. */ export type RecoveryLogStore = Pick; /** * What a variant adds to the add-and-retire entry beyond the replacement * code's own inventory, which the core appends after it: the verification * methods, and the ids each relation gains. The methods land in * `verificationMethod` and each relation in the order given, with the * replacement code's after them; nothing reads that order, since each * credential-class member names its own ladder commitment. */ export interface RecoveryAddedInventory extends RelationMembership { methods: VerificationMethod[]; services?: ServiceEndpoint[]; } /** * What one attempt of a recovery continuation returns: the superset both * variants pick their public outcome from. */ export interface RecoveryContinuationOutcome extends RecoverySpendRetirement { did: string; doc: DIDDoc; log: DIDLog; webDoc?: object; committed: boolean; } /** * One attempt of a recovery continuation, the shared control flow of * `recoverWebvhClient` and `recoverWebvhLadderAnchored`; each wraps it in the * conflict retry under its own preconditions. Both entries go through the * account-entry seam ({@link signAccountEntry}) on its committed-key arm: the * spent code's rung 0 signs the reveal-and-commit entry, and the successor * key that entry committed signs the add-and-retire entry, so the pinned * read, the carry-over precondition, the self-reveal union, the conditional * publish, and the pin advance are the seam's. The body detects a completed * run by the successor key standing authorized (reporting what the entry * retired off the log), publishes the reveal-and-commit entry unless a torn * earlier run left it standing, enters the `onCommitted` seam, and builds the * add-and-retire entry from what the variant's `added` callback hands in. * * The reveal-and-commit entry commits, in this order, the successor key's * hash, its staged partner's hash, and the replacement code's rung-0 hash -- * the ratified append order of `decisions/0007` (the replacement's comes * LAST), which the forward ladder walk reads. The * add-and-retire entry is built on the head the reveal entry's own publish * leaves standing, with no read in between; against a store whose PUT serves * no ETag it is re-read under the same pin instead, so its compare-and-swap * never degrades to an unconditional write. * * @param options {object} * @param options.store {RecoveryLogStore} * @param options.recovery {object} the spent code's update seed and public * halves * @param options.successor {object} the key the add-and-retire entry * authorizes and signs with (`updateKeyMultibase`, from `updateSeed`) and * the staged partner whose hash the reveal entry commits right after it * (`stagedKeyMultibase`: the new client's staged key, or the fresh ladder's * rung 1) * @param options.replacement {ReplacementRecoveryPublicKeys} * @param options.onCommitted {function} the persist-before-publish seam, * entered once per attempt after the reveal entry stands and before the * pivot is built; what it resolves to is handed to `added` * @param options.added {function} builds the variant's additions to the * add-and-retire entry from the account DID, the document the entry edits, * and what the seam persisted * @param [options.credentialVmIds] {function} `(did) => string[]` -- the * credential-class `keyAgreement` ids `added` will introduce, checked * against the read document before the reveal entry: one already standing * is refused with {@link RecoveryCredentialStandingError}. The transient * variant supplies its fresh credential's; the remembered variant's new * client publishes a marked pair, which is never credential-class * @param [options.expectedDid] {string} * @returns {Promise} */ export declare function recoveryContinuationOnce({ store, recovery, successor, replacement, onCommitted, added, credentialVmIds, expectedDid }: { store: RecoveryLogStore; recovery: RecoveryPublicKeys & { updateSeed: Uint8Array; }; successor: { updateKeyMultibase: string; updateSeed: Uint8Array; stagedKeyMultibase: string; }; replacement: ReplacementRecoveryPublicKeys; onCommitted: (committed: { builtOnHead: { scid: string; versionId: string; }; }) => Promise; added: (context: { did: string; doc: DIDDoc; persisted: Persisted; }) => RecoveryAddedInventory; credentialVmIds?: (did: string) => string[]; expectedDid?: string; }): Promise; //# sourceMappingURL=continuation.d.ts.map