import type { SubmissionQueue } from './submission.js'; import type { AtribRecord } from './types.js'; /** Registered anchor types per the §2.11.8 v1 registry. */ export declare const ANCHOR_TYPES: readonly ["atrib-log", "sigstore-rekor", "rfc3161-tsa", "opentimestamps"]; export type AnchorType = (typeof ANCHOR_TYPES)[number]; /** * §2.11.10 domain-separation prefix for the anchoring-claim artifact. * JCS-canonical records begin with `{`; the prefix makes the separation * between anchoring signatures and record signatures explicit. */ export declare const ANCHOR_CLAIM_PREFIX = "atrib-anchor/v1:"; /** * `kind` discriminator carried inside the flat Rekor-shaped entry body the * conformance corpus pins (spec/conformance/2.11/anchors/, `rekor-anchor-claim`). */ export declare const ANCHOR_CLAIM_KIND = "atrib-anchor-claim/v1"; /** * One anchor in a producer's anchor set. `anchor_type` absent means * `atrib-log` (the same absence-defaulting rule the `log_proofs` * discriminator uses, §2.11.9 rule (a)). */ export interface AnchorDescriptor { /** Anchor type; absent = 'atrib-log'. */ anchor_type?: AnchorType; /** * Stable anchor identity — the role `log_id` plays for logs (§2.11.9). * When absent, it is derived from the endpoint host (atrib-log) or a * per-type default. */ anchor_id?: string; /** * Submission endpoint. The spec §2.11.12 sample config uses the field * name `url`; both spellings are accepted, `url` wins when both are set. */ url?: string; /** Alias for `url` for callers that prefer the generic name. */ endpoint?: string; /** OpenTimestamps calendar endpoints (opentimestamps only). */ calendars?: string[]; /** * Optional trust material passthrough: the anchor service's public key * (base64), forwarded to verifier configuration. Not used for submission. */ public_key_b64?: string; } /** Producer anchor configuration per §2.11.12. */ export interface AnchorSetConfig { anchors?: AnchorDescriptor[]; /** * Opt-in acknowledgment that a sub-plurality anchor set is deliberate * (§2.11.12 rule 3) — the single-anchor analog of a deliberate dangling * `informed_by` claim per D113. Defaults to false. */ allow_single_anchor?: boolean; } /** * The SDK's built-in default anchor set (§2.11.12 rule 1): two independently * identified anchor descriptors. The non-atrib member is OpenTimestamps per * D138. Descriptor posture is not proof success: callers use the fan-out * report and verifier result for those claims. The OTS transport becomes * active only when a producer explicitly configures the anchor leg, so * zero-config fan-out never creates outbound HTTP traffic. */ export declare const BUILT_IN_DEFAULT_ANCHOR_SET: readonly AnchorDescriptor[]; /** * §5.9.3 sidecar degradation marker written when a sub-plurality config * lacks `allow_single_anchor` (§2.11.12 rule 4): * `_local.anchor_config = { configured: , allow_single_anchor: false }`. */ export interface AnchorConfigSidecarMarker { configured: number; allow_single_anchor: false; } /** * Result of resolving a producer anchor config per the §2.11.12 precedence * rules. Field names match the conformance corpus * (`cases/allow-single-anchor-config.json`) exactly. */ export interface AnchorPostureResolution { effective_anchor_count: number; used_default_set: boolean; warn: boolean; sidecar_anchor_config: AnchorConfigSidecarMarker | null; } /** * Resolve a producer anchor config per §2.11.12, exact precedence: * * 1. No anchor config at all ⇒ the built-in default set (two anchors). * 2. Explicit config with ≥ 2 entries ⇒ used as given. * 3. Explicit config with < 2 entries and `allow_single_anchor: true` ⇒ * used as given, no warning. * 4. Explicit config with < 2 entries and no flag ⇒ `warn: true` plus the * sidecar degradation marker. The operation continues; this function is * PURE (no console output, no throw) — the fan-out constructor emits * the `atrib:`-prefixed warning so pure-function callers stay silent. * * Never throws (§5.8). A malformed config resolves as if empty. */ export declare function resolveAnchorPosture(config?: AnchorSetConfig): AnchorPostureResolution; /** * The effective anchor set for a config: the built-in default set when no * config was given (§2.11.12 rule 1), the caller's entries otherwise — * including deliberate or warned sub-plurality sets, which are used as * given (rules 3-4: warn, never block). */ export declare function resolveEffectiveAnchors(config?: AnchorSetConfig): readonly AnchorDescriptor[]; /** * Build the §2.11.10 anchor-claim artifact bytes for a record hash: the * UTF-8 bytes of `"atrib-anchor/v1:" + record_hash` with `record_hash` in * canonical `"sha256:" + 64-lowercase-hex` form. Deterministically * reconstructible from `record_hash` alone; reveals nothing beyond the * commitment itself (§8.3 posture preserved). * * Throws TypeError on a malformed record hash — this is a pure builder for * programmer input, and the fan-out path catches everything per §5.8. */ export declare function anchorClaimArtifact(recordHash: string): Uint8Array; /** Canonical `"sha256:" + hex` hash of a signed record's COMPLETE canonical form (§1.2.3). */ export declare function canonicalRecordHash(record: AtribRecord): string; /** * A signed §2.11.10 anchoring claim, in the flat entry-body construction * the conformance corpus pins for `sigstore-rekor` elements: sorted-key * JSON of `{ artifact_b64, kind, public_key_b64url, signature_b64url }`. */ export interface AnchoringClaim { /** UTF-8 artifact: `"atrib-anchor/v1:" + record_hash`. */ artifact_utf8: string; /** Standard base64 of the artifact bytes. */ artifact_b64: string; kind: typeof ANCHOR_CLAIM_KIND; /** FRESH anchoring public key (base64url raw Ed25519). */ public_key_b64url: string; /** FRESH Ed25519 anchoring signature over the artifact bytes (base64url). */ signature_b64url: string; /** Standard base64 of the sorted-key JSON entry body. */ entry_body_b64: string; } /** * Sign a §2.11.10 anchoring claim for `recordHash` with a FRESH Ed25519 * anchoring signature over the artifact bytes. * * The anchoring key MAY be the record's `creator_key` or any third party's * key — anchoring is permissionless (§2.11.7). The record's own `signature` * MUST NOT be reused here; it does not verify over the bytes behind * `record_hash` by construction (§2.11.10). */ export declare function buildAnchoringClaim(recordHash: string, anchoringPrivateKey: Uint8Array): Promise; /** * Verify an anchoring claim against a bundle's `record_hash`: the artifact * must reconstruct from `recordHash` (binding + prefix) and the embedded * FRESH Ed25519 anchoring signature must verify over the artifact bytes. * A genuinely-signed claim for a DIFFERENT record hash returns false — it * is an invalid proof for this bundle, not equivocation (§2.11.10). * * Never throws; malformed input returns false (§5.8). */ export declare function verifyAnchoringClaim(claim: Pick, recordHash: string): Promise; export interface AnchorSubmissionRequest { record: AtribRecord; /** Canonical `"sha256:" + hex` hash of the record's complete canonical form. */ recordHash: string; priority: 'high' | 'normal'; } export type AnchorSubmissionStatus = /** Handed to the anchor's non-blocking submission path. */ 'queued' /** Accepted by the anchor but awaiting upstream attestation (e.g. OTS). */ | 'pending' /** The transport obtained an offline-verifiable proof for this commitment. */ | 'confirmed' /** No transport implementation for this anchor type yet (stub). */ | 'unsupported' /** The transport threw or rejected; caught per §5.8, never rethrown. */ | 'failed'; export interface AnchorSubmissionOutcome { anchor_type: AnchorType; anchor_id: string; status: AnchorSubmissionStatus; detail?: string; } /** * Outcome accounting for one fan-out. Configured descriptors never count as * attempts or accepted submissions. `pending` and `confirmed` mean the * upstream accepted the commitment. Only `confirmed` means the transport * obtained an offline-verifiable proof. Independent plurality is still a * verifier decision over proof bytes, trust roots, and operator groups. */ export interface AnchorSubmissionReport { configured_anchor_count: number; attempted_anchor_count: number; successful_submission_count: number; proof_ready_anchor_count: number; queued_anchor_count: number; pending_anchor_count: number; unsupported_anchor_count: number; failed_anchor_count: number; proof_ready_anchors: Array<{ anchor_type: AnchorType; anchor_id: string; }>; outcomes: AnchorSubmissionOutcome[]; } export declare function summarizeAnchorOutcomes(outcomes: AnchorSubmissionOutcome[], configuredAnchorCount?: number): AnchorSubmissionReport; /** * One anchor submission client. Implementations MUST be non-blocking in * spirit: `submit` may return a promise, but the fan-out never awaits it * before returning to the caller (§5.3.5), so slow transports only delay * their own outcome, never the primary path. */ export interface AnchorTransport { readonly anchorType: AnchorType; readonly anchorId: string; submit(request: AnchorSubmissionRequest): AnchorSubmissionOutcome | Promise; /** Drain transport-owned work during tests and host shutdown. */ flush?(): Promise; } /** Injectable fetch surface for offline adapter tests and host-owned HTTP policy. */ export type AnchorFetch = (input: string, init?: RequestInit) => Promise; export interface AnchorTransportOptions { queue?: SubmissionQueue; maxQueueDepth?: number; /** * Enables non-log HTTP submission. `createAnchorFanout` sets this only for * explicit caller configuration; direct callers opt in deliberately. */ allowNetwork?: boolean; /** Defaults to global fetch when network submission is enabled. */ fetchImpl?: AnchorFetch; } /** * The `atrib-log` transport: reuses the existing §2.6.1 non-blocking * submission path. `queue.submit` is fire-and-forget with its own retry * and eviction discipline (§5.3.5), so `submit` here returns synchronously * with `queued`. */ export declare function createAtribLogAnchorTransport(descriptor: AnchorDescriptor, options?: AnchorTransportOptions): AnchorTransport; /** * Network-disabled transport for non-log anchors. This is a safe default, * not an implementation gap: callers must explicitly configure the anchor * set before the adapters below make outbound requests. */ export declare function createStubAnchorTransport(anchorType: Exclude, anchorId: string): AnchorTransport; /** Build the minimal RFC 3161 TimeStampReq for a SHA-256 imprint. */ export declare function rfc3161TimestampQuery(recordHash: string): Uint8Array; /** Real Rekor HTTP adapter. It submits an unsigned hashedrekord claim. */ export declare function createRekorAnchorTransport(descriptor: AnchorDescriptor, options?: AnchorTransportOptions): AnchorTransport; /** Real RFC 3161 HTTP adapter using a DER TimeStampReq with a SHA-256 imprint. */ export declare function createRfc3161AnchorTransport(descriptor: AnchorDescriptor, options?: AnchorTransportOptions): AnchorTransport; /** Real OpenTimestamps calendar adapter. Accepted receipts remain pending. */ export declare function createOpenTimestampsAnchorTransport(descriptor: AnchorDescriptor, options?: AnchorTransportOptions): AnchorTransport; /** Build the default transport for one descriptor. */ export declare function createAnchorTransport(descriptor: AnchorDescriptor, options?: AnchorTransportOptions): AnchorTransport; /** * Handle returned by `submitToAnchors`. The caller MUST NOT await * `outcomes` on the primary path (§5.3.5); it exists for tests, flush * hooks, and audit sinks. */ export interface AnchorFanoutTicket { outcomes: Promise; /** Successful-leg accounting derived from settled outcomes. */ report: Promise; } export interface CreateAnchorFanoutOptions { /** Anchor-set configuration (§2.11.12). Absent = built-in default set. */ config?: AnchorSetConfig; /** * Transport injection: overrides the built-in transport for any effective * descriptor whose `(anchor_type, anchor_id)` pair matches. Extra * transports with no matching descriptor are ignored. Used by tests and * by hosts that ship their own adapters ahead of the built-in ones. */ transports?: AnchorTransport[]; /** Forwarded to atrib-log submission queues created by this fan-out. */ maxQueueDepth?: number; /** Injectable HTTP client for explicitly configured non-log anchor legs. */ fetchImpl?: AnchorFetch; /** * Observer invoked once per settled anchor leg. Errors are caught and * logged per §5.8; they never affect other legs or the caller. */ onOutcome?: (outcome: AnchorSubmissionOutcome) => void; } export interface AnchorFanout { /** The §2.11.12 posture this fan-out resolved at creation time. */ readonly posture: AnchorPostureResolution; /** * §5.9.3 sidecar degradation marker, or null. Non-null exactly when the * config warned (§2.11.12 rule 4); hosts write it to `_local.anchor_config`. */ readonly sidecarMarker: AnchorConfigSidecarMarker | null; /** The transports this fan-out submits to, in effective-set order. */ readonly transports: readonly AnchorTransport[]; /** * Fan a signed record out to every configured anchor. Returns * synchronously; never awaits any transport, never throws (§5.3.5, §5.8). */ submitToAnchors(record: AtribRecord, priority?: 'high' | 'normal'): AnchorFanoutTicket; /** Await all in-flight anchor legs (testing/shutdown only). */ flush(): Promise; } /** * Create a long-lived anchor fan-out for a producer. Resolves the §2.11.12 * posture once, emits the rule-4 `atrib:` warning when applicable (the * operation continues; signing is never disabled), and builds one transport * per effective anchor. */ export declare function createAnchorFanout(options?: CreateAnchorFanoutOptions): AnchorFanout; export interface SubmitToAnchorsOptions extends CreateAnchorFanoutOptions { priority?: 'high' | 'normal'; } /** * One-shot convenience over `createAnchorFanout`: fan a single signed * record out to the configured anchor set. Returns synchronously with an * `AnchorFanoutTicket`; never awaits, never throws (§5.3.5, §5.8). * * Long-lived producers should hold a `createAnchorFanout` instance instead * so atrib-log retry queues persist across records. */ export declare function submitToAnchors(record: AtribRecord, options?: SubmitToAnchorsOptions): AnchorFanoutTicket; //# sourceMappingURL=anchors.d.ts.map