import type { DIDDoc, DIDLog, UpdateDIDResult } from '@interop/did-method-webvh'; import type { ClientWebvhUpdateKeys, CreatedWebvhLog, DidWebKeyMapV2, PublishedWebvhLog, WebvhEnrollmentKeys, WebvhIdStore } from '../webvh/didWebvh.js'; import { type ClientRemovalTarget, type RevokedClientKeys } from '../webvh/revokeClient.js'; import { type UnlockKeyAgreementPublication, type UnlockLogStore } from '../unlock/standingWebvh.js'; import type { AccountEntryFields } from '../webvh/accountEntry.js'; import type { LadderRung, LadderRungState } from './ladder.js'; /** * LADDER-ANCHORED GENESIS: assembles the one-entry did:webvh log of an account * with zero enrolled clients, anchored on the minting credential's * ladder alone. Everything derives from the ladder seed: rung 0 is the sole * `updateKeys` member and signs the entry, `nextKeyHashes` commits rung 0's * own carry-over hash plus rung 1 (the staged rung) -- the carry-over hash is * what the first self-enrollment's reveal-and-commit entry, * re-stating `updateKeys` containing rung 0, requires -- * and the ladder VM (the stable sibling) is published under `assertionMethod` * and `capabilityDelegation` only. The credential's `keyAgreement` * entry is FOLDED INTO GENESIS -- no enrolled client exists to run the * separate bind entry ({@link publishUnlockKey}) -- so the genesis * `keyAgreement` array holds only the credential's entry. * * The account stays ladder-anchored until a self-enrollment * ({@link selfEnrollWebvhClient}) publishes a client and retires rung 0. That * entry leaves the ladder VM standing: it is struck when the credential * retires, not when a client arrives. * * When the wallet keeps a KMS, `didWebKeys` folds the KMS-held * authentication key into the entry under `authentication` only -- the * enrolled-client genesis's server-side convenience, with its exclusions * intact (no KMS keyAgreement or assertion key). * * The caller owns publication (conditional, create-only) and the pointer * write that follows; this assembles and signs the log only. * * @param options {object} * @param options.wasServerUrl {string} * @param options.spaceId {string} * @param [options.didWebKeys] {DidWebKeyMapV2} the parsed keys.json, when * the wallet keeps a KMS; absent, the genesis is ladder-and-credential-only * @param options.ladderSeed {Uint8Array} the credential's ladder seed * @param options.keyAgreement {UnlockKeyAgreementPublication} the * credential's key-agreement publication (commitment or verbatim) * @returns {Promise} */ export declare function createLadderAnchoredAccountLog({ wasServerUrl, spaceId, didWebKeys, ladderSeed, keyAgreement }: { wasServerUrl: string; spaceId: string; didWebKeys?: DidWebKeyMapV2; ladderSeed: Uint8Array; keyAgreement: UnlockKeyAgreementPublication; }): Promise; /** * LADDER-ANCHORED GENESIS AS AN ENSURE: probe, adopt, or create-and-publish -- * {@link createLadderAnchoredAccountLog} with the enrolled-client flow's * `ensureDidWebvh` convention wrapped around it. The convergence rule is what * makes signup a ceremony rather than a bare create: `createDID` timestamps * the genesis entry, so a naive re-run of a torn signup mints a DIFFERENT SCID * and its create-if-absent PUT can never land. So a published log is ADOPTED * instead -- iff `attributeLadderRung` attributes its update parameters to * this credential's ladder (rung revealed or committed; a foreign log fails * closed with `LadderAttributionError` and is never built on). * * The publish is a conditional create-if-absent, so a concurrent signup's * winner is adopted on the conflict re-run rather than erased. On the create * path the publish advances the store's own chain-head pin from the log this * run minted (the account-log trust-on-first-use convention: the creator * knows the true genesis); on the probe path the read itself carries the pin * check. * * @param options {object} * @param options.idStore {WebvhIdStore} * @param options.wasServerUrl {string} * @param options.spaceId {string} * @param [options.didWebKeys] {DidWebKeyMapV2} the parsed keys.json, when * the wallet keeps a KMS; folded into the CREATE path only (see the * adoption note in the body), which also records the minted DID into * keys.json's webvh block as the enrolled-client ensure does * @param [options.keysJsonEtag] {string} the ETag the KMS-authentication * stage's own `keys.json` write returned, carried as the `ifMatch` of that * rewrite * @param options.ladderSeed {Uint8Array} the credential's ladder seed * @param options.keyAgreement {UnlockKeyAgreementPublication} the * credential's key-agreement publication (commitment or verbatim) * @param [options.expectedDid] {string} the DID the published log must * resolve to, when the caller holds the account pointer; a heal login on a * fresh terminal legitimately holds none * @returns {Promise<{ did: string, published: PublishedWebvhLog, * logMinted: boolean }>} `published` is the head this stage stands on -- * the served one on the adopt branch, the minted one paired with its * create PUT's ETag on the create branch -- so the stage after it can build * on this head instead of re-reading the log this one just read or wrote. * Its `etag` is absent against a backend that serves none, which is one * case a later stage must still read for itself. `logMinted` says WHICH * branch produced it, which a later stage needs before reusing it: a * minted head is one no other writer could have held a moment ago, while * an adopted head is a snapshot of an account other clients are free to * write to, and the parts of it no ETag protects (the document's * completion tests) can be stale by the time a later stage reads them */ export declare function ensureLadderAnchoredDidWebvh(options: { idStore: WebvhIdStore; wasServerUrl: string; spaceId: string; didWebKeys?: DidWebKeyMapV2; keysJsonEtag?: string; ladderSeed: Uint8Array; keyAgreement: UnlockKeyAgreementPublication; expectedDid?: string; }): Promise<{ did: string; published: PublishedWebvhLog; logMinted: boolean; }>; /** * What a ladder-signed entry's `build` hands back -- the account-entry seam's * own field bundle, under the annex's name for its call sites. */ export type LadderSignedEntry = AccountEntryFields; /** * What {@link ladderSignedAccountEntry} reports. `skipped` says the * pre-attribution hook declined, so nothing was attributed and nothing was * published; `updated` is absent on that path AND where `build` itself * declined, which is the one test an idempotent caller needs ("did this call * publish an entry"). The ladder arm always attributes a rung, so `rung`, * `rungHash` and `state` stand on every non-skipped outcome -- which is what * this wrapper narrows over the seam's shared outcome. `etag` is the * published log's new validator when an entry was published and the backend * serves one. */ export type LadderSignedEntryOutcome = { skipped: true; published: PublishedWebvhLog; rung?: undefined; rungHash?: undefined; state?: undefined; updated?: undefined; } | { skipped: false; published: PublishedWebvhLog; rung: LadderRung; rungHash: string; state: LadderRungState; updated?: UpdateDIDResult; etag?: string; }; /** * ONE LADDER-SIGNED ACCOUNT-LOG ENTRY: the account-entry seam * ({@link signAccountEntry}) on its ladder arm, narrowed to the outcome the * annex's ceremonies read. The seam owns the nine steps -- the pinned read, * the rung attribution, the rung's carry-over hash, the carry-over * precondition, the update-key signer, the self-reveal union into * `updateKeys`, the carry-over union into `nextKeyHashes`, the conditional * publish (`did.jsonl` alone, the bridge's whole reach), and the pin advance. * * No conflict retry of its own: a lost compare-and-swap surfaces as a * `WebvhLogConflictError` for the caller's {@link withLogConflictRetry} to * re-run, which is what re-attributes the rung and climbs to the winner's * committed one (the retry-up-the-ladder resolution). * * @param options {object} * @param options.store {UnlockLogStore} public log read + delegated PUT, * carrying the chain-head pin the read is checked against and the publish * advances * @param options.ladderSeed {Uint8Array} the credential's ladder seed * @param [options.expectedDid] {string} the account DID the log must resolve * to, from the caller's stored account pointer * @param [options.skip] {function} `(published) => boolean` -- run on the * read, before any attribution; `true` returns `skipped` with nothing * published * @param options.build {function} * `({ published, rung, state }) => LadderSignedEntry | undefined` -- the * entry's own members, or `undefined` to decline * @param [options.beforePublish] {function} `({ updated }) => Promise` * -- the pre-publish seam, for the ceremonies that PUT their post-entry * `did:web` projection while the authority they are about to end can still * write it. See {@link signAccountEntry} * @returns {Promise} */ export declare function ladderSignedAccountEntry({ store, ladderSeed, expectedDid, skip, build, beforePublish }: { store: UnlockLogStore; ladderSeed: Uint8Array; expectedDid?: string; skip?: (published: PublishedWebvhLog) => boolean | Promise; build: (context: { published: PublishedWebvhLog; rung: LadderRung; state: LadderRungState; }) => LadderSignedEntry | undefined | Promise; beforePublish?: (built: { updated: UpdateDIDResult; }) => Promise; }): Promise; /** * SELF-ENROLLMENT (run by the credential-derived client through the delegated * `did.jsonl` PUT): writes the standing continuation described in the module * doc -- the reveal-and-commit entry signed by the attributed ladder rung, * then the add entry signed by the new ordinary client's update key, which * also retires the spent rung. Resumable from durable state alone: a * completed continuation is detected by the new client's update key already * being authorized (no-op), a torn one by the attribution finding the rung * already revealed. Both entries publish conditionally on the read they were * built on, and a race lost to a concurrent ceremony re-runs from the top -- * re-attributing, which is exactly the retry-up-the-ladder resolution. * * @param options {object} * @param options.store {UnlockLogStore} public log read + delegated PUT. * Every read the two entries are built on is checked against the store's * own chain-head pin (a served prefix is refused before the reveal entry * lands, not only by a verify that follows both entries), and the pin * advances to each entry as it publishes * @param options.ladderSeed {Uint8Array} the credential's ladder seed, from * its unlock record * @param options.newClientKeys {WebvhEnrollmentKeys} the new ordinary * client's public halves * @param options.newClientUpdateSeeds {ClientWebvhUpdateKeys} the new * client's update-key seeds (minted by the self-enrolling flow, which * therefore holds them and can sign the add entry) * @param options.onCommitted {function} * `(committed: { builtOnHead: { scid, versionId } }) => Promise` -- * the REQUIRED persist-before-publish seam. It runs once per attempt, after * the reveal-and-commit entry stands (published here, or standing from a * torn earlier run) and BEFORE the add entry -- the ceremony's pivot -- is * built. The caller writes the pending client-key record to client-local * storage there (the `pending` codec group of `keys/clientKeyRecord.ts`: * ceremony `'self-enrollment'`, the handed-back `builtOnHead`), so the add * entry can never publish a client whose seed nothing can re-derive, per the * post-pivot derivability rule (`decisions/0010`). A throw propagates and * the add entry is withheld. What a throw leaves behind is inert: the * standing reveal entry's committed hashes for the unpersisted client stay * in `nextKeyHashes` forever as orphans, but they commit keys of a lost * random seed -- nothing can reveal them, so they are no re-seizure * credential, and the per-entry staged-hash attribution passes over them. * The seam must be idempotent: the conflict retry and a resumed run invoke * it again. `builtOnHead` is the head of the log snapshot the add entry is * about to be built on -- the SCID from the log's parameters and the latest * entry's `versionId` -- which a resume hands back as this call's * `builtOnHead` marker. The caveat to hold on to: the idempotent COMPLETED * branch (the new client's update key already authorized) returns without * ever entering the seam, so a caller resuming across processes must be * able to treat an already-complete continuation as success on its own * @param [options.builtOnHead] {object} `{ scid, versionId }` -- the resume * marker a pending record recorded, from an earlier run's `onCommitted`. * Supplied, the attempt's first read is refused with * {@link BuiltOnHeadNotReachedError} unless the served log carries that * SCID and an entry with that `versionId`. The chain-head pin cannot stand * in for it: the pin is written non-atomically after the add entry * publishes, and the continuity check accepts a log served at exactly the * pinned length -- so only this marker stops a resume rebuilding the add * entry over a log that never reached the head the pending record was * written against. The marker covers the pre-pivot half of that gap only: * a served log CONTAINING the recorded head but truncated behind the torn * run's own add entry still passes it and is resumed onto, and the menders * for that residual half are the ordinary ones -- this client's own * chain-head pin once the add publish wrote it, and any other enrolled * client's pinned read of the same log. Both members must be non-empty * strings; a malformed marker is refused with a `TypeError` before any * read, since a resume with an uncomparable marker is a resume with no * fork guard * @param [options.expectedDid] {string} the account DID the log must resolve * to, from the credential-authenticated pointer * @returns {Promise<{ did: string, webDoc?: object, committed: boolean }>} * the account DID, the final `did.json` projection when the add entry ran * here, and `committed` -- whether THIS call published the pivot entry * (`false` exactly on the idempotent completed branch, where a torn earlier * run had already published it). It is an observability signal, not a * success flag: a returning call means the continuation stands either way, * so a caller clears its pending record on the RETURN, whatever `committed` * says. Its absence from a return value is a build skew, which is why it is * stated rather than inferred */ export declare function selfEnrollWebvhClient(options: { store: UnlockLogStore; ladderSeed: Uint8Array; newClientKeys: WebvhEnrollmentKeys; newClientUpdateSeeds: ClientWebvhUpdateKeys; onCommitted: (committed: { builtOnHead: { scid: string; versionId: string; }; }) => Promise; builtOnHead?: { scid: string; versionId: string; }; expectedDid?: string; }): Promise<{ did: string; webDoc?: object; committed: boolean; }>; /** * Refuses a malformed resume marker before any read. A marker whose members * are missing or empty could not be compared against anything, so accepting * one would hand a resume the mint-skip WITHOUT the fork guard the marker * exists to apply -- fail-open exactly where the guard matters. * * @param options {object} * @param options.builtOnHead {unknown} the supplied marker * @returns {void} */ export declare function assertBuiltOnHeadShape({ builtOnHead }: { builtOnHead: unknown; }): void; /** * Thrown when a resumed self-enrollment is served an account log that has not * reached the head its pending record was written against -- a different SCID, * or no entry carrying the recorded `versionId`. Rebuilding the add entry over * such a log would fork the account off a head the ceremony already committed * to, which the chain-head pin alone does not catch: the pin is written * non-atomically after the add entry publishes, so a run torn between the two * leaves a pin one entry behind, and the continuity check accepts a served log * at exactly the pinned length. * * **`name` is a stable contract.** It is always the string * `'BuiltOnHeadNotReachedError'`, and a consumer should match on that rather * than on `instanceof`: a wallet app that links this package (or holds two * copies of it through a dependency tree) gets a different class object for * the same error, so `instanceof` silently fails there while the name does * not. */ export declare class BuiltOnHeadNotReachedError extends Error { /** * The head the pending record recorded, which the served log did not reach. */ builtOnHead: { scid: string; versionId: string; }; /** * @param options {object} * @param options.builtOnHead {object} the recorded `{ scid, versionId }` */ constructor({ builtOnHead }: { builtOnHead: { scid: string; versionId: string; }; }); } /** * Thrown when the client being forgotten is the account's LAST enrolled * client. Removing it through this entry would leave the document * with no client and no ladder verification method -- an account nothing can * invoke for -- so that case is its own ceremony (the two-entry * ladder-VM-install shape), and this primitive refuses rather than * transitioning the account by accident. * * **`name` is a stable contract.** It is always the string * `'LastEnrolledClientForgetError'`, and a consumer should match on that * rather than on `instanceof`: a wallet app that links this package (or holds * two copies of it through a dependency tree) gets a different class object * for the same error, so `instanceof` silently fails there while the name * does not. */ export declare class LastEnrolledClientForgetError extends Error { constructor(); } /** * FORGET (run by the forgetting client itself, through the standing * credential's bridge): removes THIS browser's enrolled client from the * published document in ONE atomic ladder-signed entry -- self-enrollment in * reverse, collapsed to a single entry because a removal reveals no new key. * The signer is the credential's current ladder rung, recovered from the log * itself ({@link attributeLadderRung}): its hash stands committed by the * credential's inventory (or the rung is already revealed), which is exactly * what lets it reveal itself in the entry it signs under prerotation. The * entry's members are the revocation removal's, verbatim * (`clientRemovalTarget` / `clientRemovalFields`, shared with * `revokeWebvhClient` so the two removal shapes cannot drift): the client's * verification methods out of the document and all five relations, its update * key out of `updateKeys`, and its carry-over and staged hashes out of * `nextKeyHashes` -- plus the acting rung into `updateKeys` with its own hash * kept committed (the carry-over convention). * * Atomicity is the point of the one-entry shape: no torn state exists where * the rung is revealed and the client still stands. The honest residue is the * acting rung itself -- no entry can remove its own signing key, so the rung * stands REVEALED in `updateKeys` afterwards (the same standing state the * ladder-anchored accounts live in). That is credential-held authority, not * the forgotten client's: only the ladder seed derives it, the credential's * next self-enrollment consumes and retires it, and retiring the credential * itself strikes it (`attributeLadderInventory`). * * Forgetting the LAST enrolled client is refused * ({@link LastEnrolledClientForgetError}): that transition -- to the * client-less, ladder-anchored state -- is its own two-entry ceremony. * * Idempotent: a client with no remaining presence is a no-op that returns the * published state unchanged, so a naive re-run after a torn ceremony * converges. The entry publishes conditionally on the log this call read; a * lost race re-runs, re-attributes, and rebases on the winner's head. * * @param options {object} * @param options.store {UnlockLogStore} the credential's delegated * `did.jsonl` bridge store; the read inside each attempt is checked against * its chain-head pin (a served truncated prefix is refused as a `rollback` * before anything is built on it), and the pin advances to the head this * entry publishes * @param [options.projectionStore] {object} an `id`-collection store the * FORGETTING client can still write through (its own root-invoking store): * the post-removal `did:web` projection is PUT through it immediately * before the removal entry publishes, and only when this run publishes that * entry. See {@link clientForgetEntryOnce} for the ordering rationale. * Omitted, `did.json` keeps naming the forgotten client until some later * writer runs `ensureDidWebProjection` * @param options.ladderSeed {Uint8Array} the credential's ladder seed * @param options.forgottenClient {RevokedClientKeys} this client's public * halves; an `updateKeyMultibase` the log does not authorize (stale, or the * staged key) is re-derived from the log * @param [options.knownLatentHashes] {string[]} standing latent commitments * the caller vouches for (the recovery registry's update-key hashes), * excluded from the staged-hash attribution * @param [options.expectedDid] {string} the account DID the log must resolve * to, from the caller's stored account pointer * @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} the account * DID and the document and log as the removal entry leaves them (unchanged * on the idempotent no-op path) */ export declare function forgetWebvhClient(options: { store: UnlockLogStore; projectionStore?: Pick; ladderSeed: Uint8Array; forgottenClient: RevokedClientKeys; knownLatentHashes?: string[]; expectedDid?: string; }): Promise<{ did: string; doc: DIDDoc; log: DIDLog; }>; /** * One attempt of {@link forgetWebvhClient} or `forgetLastWebvhClient` * (`forgetLast.ts`), re-invoked by their conflict retries. The two share the * whole removal entry and differ only in what makes the removal admissible, * which each supplies as `assertRemovable` -- the plain forget refuses the * last enrolled client, the transition removal requires the ladder VM already * installed. The invariant travels with the ceremony that owns it rather than * living here as a flag. * * THE PROJECTION IS PUBLISHED BEFORE THE ENTRY, and the order is forced: the * removal entry is ladder-signed and publishes `did.jsonl` alone (the bridge * delegation covers nothing else), while the forgotten client's authority * dies at that entry under the current-key-set rule. So the post-removal * `did:web` projection has to be written while that client can still write * it. A run torn between the projection PUT and the entry leaves `did.json` * omitting a client the log still lists, which is fail-closed for a `did:web` * verifier and is re-PUT by the re-run; the reverse order would leave the * revoked client standing in `did.json` with nothing left able to remove it. * The idempotent already-forgotten path writes no projection at all: the * removal entry landed on an earlier run, so this client's authority is * already gone and its store can only be refused. A projection that path * leaves stale is mended by the next transient visit's * `ensureDidWebProjection`, which invokes under its generation delegation. * * @param options {object} see {@link forgetWebvhClient}, plus: * @param options.assertRemovable {function} * `({ published, target }) => void` -- run on the read, after the * idempotent already-forgotten check and before anything is attributed or * built; it throws to refuse the removal * @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} */ export declare function clientForgetEntryOnce({ store, projectionStore, ladderSeed, forgottenClient, knownLatentHashes, expectedDid, assertRemovable }: { store: UnlockLogStore; projectionStore?: Pick; ladderSeed: Uint8Array; forgottenClient: RevokedClientKeys; knownLatentHashes?: string[]; expectedDid?: string; assertRemovable: (options: { published: PublishedWebvhLog; target: ClientRemovalTarget; }) => void | Promise; }): Promise<{ did: string; doc: DIDDoc; log: DIDLog; }>; /** * THE LADDER-VM INSTALL ENTRY (the two-entry transition ceremony's first * entry): publishes the credential's ladder VM -- the stable sibling, under * `assertionMethod` and `capabilityDelegation` only -- leaving every enrolled * client's inventory untouched. A ladder VM and enrolled clients are * co-resident by design: the VM's life is keyed to its credential, so the * document carries one per standing credential for as long as that credential * stands. The entry is * ladder-signed by the attributed rung, which reveals itself into * `updateKeys` with its own hash kept committed (the carry-over convention), * exactly the removal entry's rung math -- so a torn ceremony's re-run * re-attributes the now-revealed rung and carries on. * * This entry is what makes the transition's document version INVENTORY-CHANGING * under the ceremony-tail license (the ladder-VM set gains a member), so the * ceremony's ONE ladder-signed roster append anchors here -- and it is what * lets the delegation revocations that follow verify their ladder-signed * chains against the currently resolved document while the still-standing * client signs the invocations. * * Idempotent: a document already carrying this credential's ladder VM (by * the relation-asymmetry recognition) returns unchanged with * `installed: false`. The entry publishes conditionally on the log this call * read; a lost race re-runs, re-attributes, and rebases on the winner's * head. * * @param options {object} * @param options.store {UnlockLogStore} the credential's delegated * `did.jsonl` bridge store; the read inside each attempt is checked against * its chain-head pin, and the pin advances to the head this entry publishes * @param options.ladderSeed {Uint8Array} the credential's ladder seed * @param [options.expectedDid] {string} the account DID the log must resolve * to, from the caller's stored account pointer * @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog, installed: boolean }>} * the account DID and the document and log as the install entry leaves them * (unchanged on the idempotent no-op path); `installed` says whether the * entry ran on this call */ export declare function installLadderVmWebvh(options: { store: UnlockLogStore; ladderSeed: Uint8Array; expectedDid?: string; }): Promise<{ did: string; doc: DIDDoc; log: DIDLog; installed: boolean; }>; /** * THE LADDER-VM STRIKE ENTRY: takes THIS credential's ladder VM out of the * document -- from `verificationMethod`, `assertionMethod`, and * `capabilityDelegation` -- and touches nothing else. The id comes from the * ladder seed, so the strike reaches one credential's VM: another standing * credential's ladder VM, and every enrolled client's inventory, stand * untouched. The account-wide filter the transient recovery's add-and-retire * entry runs is a different rule and stays there. * * Paired with {@link installLadderVmWebvh} it is the last-client * transition's opening move: the strike, then the reinstall of the identical * VM. That pair is what supplies the transition with an * inventory-changing document version for its one ladder-signed roster * append, on an account whose VM already stands (the credential-keyed * lifecycle installs it at bind time). The republished node is the same * `#`, and a zcap delegation proof carries no version * anchor, so any unexpired ladder-signed delegation resumes verifying. * * Ladder-signed by the attributed rung, which reveals itself into * `updateKeys` with its own hash kept committed (the carry-over convention) * -- the install and removal entries' rung math exactly. * * Idempotent: a document carrying no ladder VM of this credential's returns * unchanged with `struck: false`. The entry publishes conditionally on the * log this call read; a lost race re-runs, re-attributes, and rebases on the * winner's head. * * @param options {object} * @param options.store {UnlockLogStore} the credential's delegated * `did.jsonl` bridge store; the read inside each attempt is checked against * its chain-head pin, and the pin advances to the head this entry publishes * @param options.ladderSeed {Uint8Array} the credential's ladder seed * @param [options.expectedDid] {string} the account DID the log must resolve * to, from the caller's stored account pointer * @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog, struck: boolean }>} * the account DID and the document and log as the strike entry leaves them * (unchanged on the idempotent no-op path); `struck` says whether the entry * ran on this call */ export declare function strikeLadderVmWebvh(options: { store: UnlockLogStore; ladderSeed: Uint8Array; expectedDid?: string; }): Promise<{ did: string; doc: DIDDoc; log: DIDLog; struck: boolean; }>; /** * THE STANDALONE REVEAL-AND-COMMIT ENTRY: reveals this credential's currently * committed ladder rung into `updateKeys`, keeping its own hash committed and * committing the next rung's (the carry-over convention). It is the same * entry {@link selfEnrollWebvhClient} writes first, minus the enrolling * client's hashes, and it exists so a credential-only visit can sign an * account-log entry of its own -- the `#DelegatedClients` pointer move -- on * an account whose self-enrollment already spent the previously revealed * rung. * * A rung already revealed (a torn earlier run, or a racing ceremony that got * there first) is a no-op: nothing is published and `revealed: false` comes * back. A ladder the log commits no rung of at all, and an ambiguous * attribution, fail closed with `LadderAttributionError`. * * This entry retires nothing. The revealed rung stands in `updateKeys` until * a later self-enrollment's add entry spends it or the credential retires; * the caller's comment states the consequence at its own site. * * No conflict retry of its own: a caller pairing this entry with a second one * must run both inside ONE {@link withLogConflictRetry}, so a race lost * between them re-runs the attribution rather than signing with a rung the * winner consumed. * * @param options {object} * @param options.store {UnlockLogStore} the credential's delegated * `did.jsonl` bridge store; the read is checked against its chain-head pin, * and the pin advances to the head this entry publishes * @param options.ladderSeed {Uint8Array} the credential's ladder seed * @param [options.expectedDid] {string} the account DID the log must * resolve to, from the caller's stored account pointer * @returns {Promise<{ revealed: boolean, rung: LadderRung, * published: PublishedWebvhLog }>} whether this call published the * entry; the rung the attribution resolved, which stands REVEALED in * `published.updateKeys` either way (it was revealed already, or this entry * revealed it); and the head this call leaves standing -- the post-entry * head when it published, the read it was built on when the rung was * revealed already -- so a caller signing its next entry with the rung * builds on this head instead of re-reading and re-attributing a log that * provably did not change in between */ export declare function revealLadderRungWebvh({ store, ladderSeed, expectedDid }: { store: UnlockLogStore; ladderSeed: Uint8Array; expectedDid?: string; }): Promise<{ revealed: boolean; rung: LadderRung; published: PublishedWebvhLog; }>; //# sourceMappingURL=ladderAnchored.d.ts.map