import type { DIDDoc, DIDLog, UpdateDIDInterface, UpdateDIDResult } from '@interop/did-method-webvh'; import type { ClientWebvhUpdateKeys, PublishedWebvhLog, WebvhIdStore } from './didWebvh.js'; import type { LadderRung } from '../unlock/ladderDerivation.js'; import type { LadderRungState } from '../clientAnnex/ladder.js'; /** * Who signs an account-log entry. The client arm carries an enrolled client's * own did:webvh update-key seeds; the ladder arm carries a standing unlock * credential's ladder seed, whose rungs sign through the credential's bridge * delegation. A ceremony body accepts no other arm and no absence: every one * that extends the account log states which of the two it acts as. The * seam's own committed-key arm is {@link AccountEntrySigner}'s. */ export type AccountLogSigner = { kind: 'client'; updateKeys: ClientWebvhUpdateKeys; } | { kind: 'ladder'; ladderSeed: Uint8Array; }; /** * Who may sign through {@link signAccountEntry} itself: the two ceremony arms * plus the committed-key arm, a bare update-key seed whose key the published * log commits or already authorizes. Kept apart from {@link AccountLogSigner} * so no ceremony body widens what it accepts by taking the seam's type. */ export type AccountEntrySigner = AccountLogSigner | { kind: 'committed'; updateSeed: Uint8Array; }; /** * The store an account-log entry is read and published through: the public * log read and the `did.jsonl` PUT. A subset of {@link WebvhIdStore}, so both * a controller-invoking client's store and a credential's bridge-backed * unlock-log store satisfy it. */ export type AccountLogStore = Pick; /** * What a build hands back: the `updateDID` parameters the entry sets, minus * the three {@link signAccountEntry} owns (`log`, `signer`, * `alsoKnownAsWeb`). * * `updateKeys` and `nextKeyHashes` default to the published sets; a build * whose entry REMOVES members (a removal entry) states the filtered set * instead. On the ladder arm the acting rung's key is unioned into the former * and the rung's own hash into the latter -- the self-reveal and carry-over * conventions, applied in one place rather than remembered per site. */ export interface AccountEntryFields extends Omit { /** * The hashes this entry newly commits, appended AFTER the acting rung's * carry-over hash. The position is wire behavior rather than a detail: * `decisions/0007-ladder-reveal-hash-order.md` ratifies the append order a * reveal-and-commit entry produces, and a seedless ladder walk reads that * order both forwards and backwards. */ commitHashes?: string[]; } /** * What {@link signAccountEntry} reports. `skipped` says the pre-signature * 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"). `rung`, `rungHash` and `state` are the ladder arm's, absent on the * client arm. */ export type AccountEntryOutcome = { skipped: true; published: PublishedWebvhLog; rung?: undefined; rungHash?: undefined; state?: undefined; updated?: undefined; etag?: undefined; } | { skipped: false; published: PublishedWebvhLog; rung?: LadderRung; rungHash?: string; state?: LadderRungState; updated?: UpdateDIDResult; etag?: string; }; /** * The head an entry leaves standing, assembled from what the entry's own * `updateDID` already resolved plus the publish's validator when an entry was * published, and the read the entry was built on verbatim when the build * declined (the head is then provably unchanged by this call). No second read * and no second resolve: the update-key parameters are the ones the entry * itself stated, so a caller building its next entry on this head signs * against exactly what it published. * * @param options {object} * @param options.outcome {AccountEntryOutcome} * @returns {PublishedWebvhLog} */ export declare function accountEntryHead({ outcome }: { outcome: AccountEntryOutcome; }): PublishedWebvhLog; /** * Signs and publishes one account-log entry, preamble and postamble * included -- the pinned read, the signer arm's own preconditions, the * `updateDID` call, the conditional publish, and the pin advance. See the * module doc for what each arm owns. * * The caller supplies only what differs: an optional pre-signature `skip` * (the idempotent no-op every ceremony detects from stored state, checked * BEFORE any ladder attribution so a retired or never-bound credential's * re-run returns unchanged instead of failing closed on the attribution), * and a `build` that shapes the entry from the read and, on the ladder arm, * the attributed rung. A `build` returning `undefined` declines * post-attribution -- the same no-op, for a ceremony whose completion test * needs the rung. * * @param options {object} * @param options.idStore {AccountLogStore} the log read and the * `did.jsonl` PUT * @param options.signer {AccountEntrySigner} who signs this entry * @param options.build {function} * `({ published, rung, state }) => AccountEntryFields | undefined` -- the * entry's own members, or `undefined` to decline * @param [options.skip] {function} `(published) => boolean` -- run on the * read, before any attribution; `true` returns `skipped` with nothing * published * @param [options.published] {PublishedWebvhLog} a read the caller already * made (checked against `expectedDid`), in place of this call's own read. * The caller owns the staleness: a lost compare-and-swap surfaces as a * conflict for its retry to re-run * @param [options.expectedDid] {string} the account DID the log must * resolve to, from the caller's stored account pointer. The store's own * chain-head pin checks the read and advances to the head this entry * publishes * @param [options.missingMessage] {string} the thrown `Error`'s message * when `did.jsonl` is absent * @param [options.verb] {string} what the caller is doing, for the client * arm's pending-rotation refusal message (e.g. `'revoking a client'`) * @param [options.logOnly] {boolean} publish `did.jsonl` without its * `did:web` projection. Defaults per arm: `true` on the ladder arm, whose * bridge reaches `did.jsonl` alone, and `false` on the client arm, which * invokes as the controller. A ladder-signed entry written through a * root-invoking store (the establishment's stage 3) passes `false` to * republish the projection beside the entry; the committed arm states it, * since which store it signs through is the caller's * @param [options.beforePublish] {function} `({ updated }) => Promise` * -- run on the built entry, AFTER `updateDID` and BEFORE the conditional * publish. The seam exists for the `did:web` projection: a ladder-signed * entry writes `did.jsonl` alone, so a ceremony whose entry removes * inventory has to publish the post-entry projection while the authority it * is about to end can still write it. A throw propagates and nothing is * published. It runs once per attempt, so a conflict retry invokes it again * and it must be idempotent * @returns {Promise} */ export declare function signAccountEntry({ idStore, signer, build, skip, published: alreadyRead, expectedDid, missingMessage, verb, logOnly, beforePublish }: { idStore: AccountLogStore; signer: AccountEntrySigner; build: (context: { published: PublishedWebvhLog; rung?: LadderRung; state?: LadderRungState; }) => AccountEntryFields | undefined | Promise; skip?: (published: PublishedWebvhLog) => boolean | Promise; published?: PublishedWebvhLog; expectedDid?: string; missingMessage?: string; verb?: string; logOnly?: boolean; beforePublish?: (built: { updated: UpdateDIDResult; }) => Promise; }): Promise; /** * The head a ceremony concludes on when its entry turns out to be * unnecessary -- the client is already enrolled, the removal already landed. * There is nothing to publish either way; what differs is the `did:web` * projection. The client arm invokes as the account's controller, so it * republishes the projection and heals a lag a torn earlier run of the same * ceremony left behind. The ladder arm's bridge reaches `did.jsonl` alone, so * it takes the read verbatim and leaves the projection to * `ensureDidWebProjection`. * * @param options {object} * @param options.idStore {WebvhIdStore} * @param options.signer {AccountLogSigner} the arm the ceremony acts as * @param options.published {PublishedWebvhLog} the read the build stood on * @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} */ export declare function concludeUnchangedAccountEntry({ idStore, signer, published }: { idStore: WebvhIdStore; signer: AccountLogSigner; published: PublishedWebvhLog; }): Promise<{ did: string; doc: DIDDoc; log: DIDLog; }>; //# sourceMappingURL=accountEntry.d.ts.map