import { type MethodRegistry, type SigningIdentity } from '@kokuin/token'; import type { CustodyGuard, CustodyPinHooks, StoreProvider } from '@kubun/db'; import { type RecordTypeDefinition, type SignedRecord } from '@kubun/records'; import { type CatalogLevel, type ScopeCatalogRef } from '@kubun/store-graph'; import type { CatalogRecordDeps } from './catalog-records.js'; export declare const CUSTODY_TYPE = "catalog.custody"; export declare const CUSTODY_ACCEPTANCE_TYPE = "catalog.custody-acceptance"; export declare const CUSTODY_ELIGIBILITY_TYPE = "catalog.custody-eligibility"; /** The engine metadata key of this device's custody opt-in, once set by its owner. */ export declare const CUSTODY_ELIGIBLE_SETTING = "custody.eligible"; /** The levels at which a device keeps a catalog's documents, and so may guard them. */ export type CustodyLevel = Extract; export type CustodyAssignmentMeta = { catalogOwner: string; catalogID: string; generation: number; }; export type CustodyAcceptanceMeta = { catalogOwner: string; catalogID: string; assignmentDigest: string; level: CustodyLevel; }; /** A device's word on whether it takes custody of its owner's catalogs at all. */ export type CustodyEligibilityMeta = { eligible: boolean; }; export declare class CustodyAcceptanceLevelError extends Error { get code(): string; constructor(); } export declare class CustodyNotAssignedError extends Error { get code(): string; constructor(); } /** A named custodian is not a current bound own device of the custody owner. */ export declare class CustodianUnavailableError extends Error { get code(): string; constructor(options?: ErrorOptions); } /** Assigning custodians signs a record: an engine without a signing identity cannot. */ export declare class CustodySignerRequiredError extends Error { get code(): string; constructor(); } /** No other custodian has accepted the current assignment: this device may hold the only copy. */ export declare class CustodyOnlyCopyError extends Error { get code(): string; constructor(); } /** A newer assignment was stored meanwhile: the assignment must be made again over it. */ export declare class CustodyAssignmentSupersededError extends Error { get code(): string; constructor(); } /** The assignment's id within the custody owner's records. */ export declare function custodyRecordID(catalog: ScopeCatalogRef): string; /** One acceptance slot per device: a device can write only its own. */ export declare function custodyAcceptanceRecordID(catalog: ScopeCatalogRef, device: string): string; /** One eligibility slot per device, across every catalog of the custody owner. */ export declare function custodyEligibilityRecordID(device: string): string; /** The custody record types, both carried only by the custody owner's own-agents group. */ export declare function custodyRecordTypes(deps: CatalogRecordDeps): Array<[string, RecordTypeDefinition]>; /** This device's custody opt-in: its owner's stored choice, else the engine's default. */ export declare function readCustodyEligible(provider: StoreProvider, fallback: boolean): Promise; /** Store this device's custody opt-in, over the engine's default from now on. */ export declare function writeCustodyEligible(provider: StoreProvider, eligible: boolean): Promise; export type PublishCustodyEligibilityParams = { provider: StoreProvider; signer: SigningIdentity; custodyOwner: string; eligible: boolean; hlc: string; methods?: MethodRegistry; }; /** Sign and store this device's eligibility for the owner, unless it already reads so. */ export declare function publishCustodyEligibility(params: PublishCustodyEligibilityParams): Promise; /** * The custodies this device guards: its acceptance of the current winning assignment, while that * assignment still names it. An acceptance bound to a superseded assignment guards nothing. */ export declare function activeCustodyGuards(provider: StoreProvider, device: string, methods?: MethodRegistry): Promise>; /** The same guard check as the custody scan, for a known acceptance slot. */ export declare function isActiveCustodyGuard(provider: StoreProvider, device: string, custodyOwner: string, catalog: ScopeCatalogRef, methods?: MethodRegistry, assignment?: CustodyAssignment): Promise; export type CustodyAssignment = { custodyOwner: string; catalog: ScopeCatalogRef; /** The claim digest an acceptance binds to. */ digest: string; /** Sorted, normalized device DIDs. */ custodians: Array; }; /** The current winning assignment of a custody, or null when none verifies. */ export declare function currentCustodyAssignment(provider: StoreProvider, custodyOwner: string, catalog: ScopeCatalogRef, methods?: MethodRegistry): Promise; /** Every custody's current winning assignment that verifies. */ export declare function listCustodyAssignments(provider: StoreProvider, methods?: MethodRegistry): Promise>; /** The claim digest of the current winning assignment of a custody, or null when none verifies. */ export declare function currentCustodyAssignmentDigest(provider: StoreProvider, custodyOwner: string, catalog: ScopeCatalogRef, methods?: MethodRegistry): Promise; /** * Ref recompute pins through these, inside the transaction it runs in. Without the p2p store * there is no binding evidence, so every owner but the custody owner reads unresolved. */ export declare function custodyPinHooks(device: string, methodsFor?: (stores: StoreProvider) => MethodRegistry): CustodyPinHooks; export type AcceptCustodyParams = { provider: StoreProvider; signer: SigningIdentity; custodyOwner: string; catalog: ScopeCatalogRef; hlc: string; methods?: MethodRegistry; }; /** * Sign and store this device's acceptance of the current assignment. Only this device can read * its level, so the level is checked here and signed into the acceptance. */ export declare function acceptCustody(params: AcceptCustodyParams): Promise; export type CustodyStatus = 'NONE' | 'PENDING' | 'PARTIAL' | 'READY'; export type CustodyView = { custodians: Array; accepted: Array; /** Named custodians whose last word is that they take no custody. */ declined: Array; status: CustodyStatus; }; export type ReadCustodyParams = { provider: StoreProvider; custodyOwner: string; catalog: ScopeCatalogRef; methods?: MethodRegistry; }; /** The current assignment's custodians and which of them accepted it. */ export declare function readCustody(params: ReadCustodyParams): Promise; export type AssignCustodyParams = { /** A transaction: the key lock is held from the generation read to the write. */ provider: StoreProvider; signer: SigningIdentity; custodyOwner: string; catalog: ScopeCatalogRef; /** Already checked as current own devices of the custody owner; stored unique and sorted. */ custodians: Array; hlc: string; methods?: MethodRegistry; }; /** Sign and store an assignment one generation past the current winner. */ export declare function assignCustody(params: AssignCustodyParams): Promise; export type ReconcileCustodyAcceptancesParams = { provider: StoreProvider; signer: SigningIdentity; nextHLC: () => string; methods?: MethodRegistry; /** This device's custody opt-in. An ineligible device accepts nothing and says so. */ eligible?: boolean; /** Called after each acceptance commits. */ onAccepted?: (assignment: CustodyAssignment) => void; /** Called after this device's eligibility for a custody owner was stored anew. */ onEligibilityPublished?: (custodyOwner: string) => void; }; /** * Accept every current assignment naming this device that it has not accepted yet. Returns how * many it accepted. A device below `OFFLINE` stays named but unaccepted until its level rises. * An ineligible device accepts none, keeps what it already guards, and publishes its eligibility * to each custody owner naming it, so the owner can read it declined. */ export declare function reconcileCustodyAcceptances(params: ReconcileCustodyAcceptancesParams): Promise; export type LeaveCustodyParams = { /** A transaction: the assignment write and any pin release commit together. */ provider: StoreProvider; signer: SigningIdentity; custodyOwner: string; catalog: ScopeCatalogRef; /** Release this device's pins now, without another custodian's receipt. Deletes nothing. */ force: boolean; hlc: string; nowMS: number; methods?: MethodRegistry; }; /** * Step this device out of a custody: the next generation names every current custodian but it. * Refused while no other custodian has accepted the current assignment, unless forced. Without * force the pins go only through the handoff, after another custodian's receipt. Returns whether * an assignment was written. */ export declare function leaveCustody(params: LeaveCustodyParams): Promise;