import { type ChainAdapter, type ChainEventLogBindingSource, type RpcUsageWindow } from '@origintrail-official/dkg-chain'; import { type Ed25519Keypair } from '@origintrail-official/dkg-core'; import { AsyncLiftRunner, type AsyncLiftRunnerConfig, DKGPublisher, type ACKTransportFactory, type AsyncKnowledgeAssetVmPublishRecoveryResolver, type AsyncLiftDetailedRetrier, type AsyncLiftPublisher, type AsyncLiftPublisherConfig, type VmPublisherControl, type PublishOptions, type SnapshotPageIndexStore, type WorkspacePublicSnapshotStore } from '@origintrail-official/dkg-publisher'; import { type TripleStore } from '@origintrail-official/dkg-storage'; import { type DkgConfig, type PublisherRetryTuning } from './config.js'; import { type RuntimeEvmChainConfig } from './runtime-chain-config.js'; import { type PublisherChainAdapters } from './publisher-chain-proof.js'; export type { ACKTransportFactory } from '@origintrail-official/dkg-publisher'; /** Single construction boundary for every async-publisher wallet adapter. */ export declare function createPublisherWalletChain(chainBase: RuntimeEvmChainConfig | undefined, privateKey: string, chainEventLogBindingSource?: ChainEventLogBindingSource): ChainAdapter; export interface PublisherRuntime { readonly runner: AsyncLiftRunner; readonly publisher: AsyncLiftPublisher; readonly walletIds: string[]; readonly wallets: readonly PublisherRuntimeWallet[]; readonly stop: () => Promise; /** RpcUsageDrainable: merged window across every per-wallet chain adapter. */ readonly drainRpcUsage: () => RpcUsageWindow; /** * GH#2270 follow-up (🔴 3822987482) — can THIS runtime settle a held job signed by this * wallet, for this operation kind? The daemon's ADMISSION instance is a separate, deliberately * resolver-less publisher (it runs no scheduler), so asking it whether an automatic exit exists * always answered "no" — every pending-chain-proof rejection claimed there was no automatic * recovery even on a node where recovery was configured and running. Admission now asks the * live runtime through this probe instead of inferring from its own wiring. */ readonly canSettleHeldJob: (walletId: string, operationKind: 'create' | 'update' | undefined) => boolean; } export interface PublisherRuntimeWallet { readonly address: string; readonly identityId: bigint; } export type AsyncPublisherUnavailableReason = 'publisher_disabled' | 'publisher_starting' | 'no_publisher_wallets' | 'publisher_startup_failed'; type PublisherDisabledAvailability = { available: false; reason: 'publisher_disabled'; retryable: false; operatorActionRequired: true; }; type PublisherStartingAvailability = { available: false; reason: 'publisher_starting'; retryable: true; operatorActionRequired: false; }; type NoPublisherWalletsAvailability = { available: false; reason: 'no_publisher_wallets'; retryable: false; operatorActionRequired: true; }; type PublisherStartupFailedAvailability = { available: false; reason: 'publisher_startup_failed'; retryable: false; operatorActionRequired: true; }; type AsyncPublisherUnavailableAvailability = PublisherDisabledAvailability | PublisherStartingAvailability | NoPublisherWalletsAvailability | PublisherStartupFailedAvailability; export type AsyncPublisherAvailability = { available: true; } | AsyncPublisherUnavailableAvailability; /** * Canonical readiness boundary for every async-ingress route. Lifecycle may * supply an explicit starting/failure state; otherwise the runtime/config * shape is classified consistently for direct route tests and embedded users. */ export declare function resolveAsyncPublisherAvailability(args: { config: DkgConfig; runtime: PublisherRuntime | null; lifecycleReason?: AsyncPublisherUnavailableReason; }): AsyncPublisherAvailability; export interface PublisherInspector { /** * GH#2270 — also the detailed retrier, so `dkg publisher retry` reports the same three * counts with or without a running daemon. `AsyncLiftRetryStateReader` is deliberately NOT * exposed here: this instance is built without the operator's `config.publisher` retry * knobs, so its `autoRetryEligible` could contradict the lane that actually runs. The * detailed retry counts carry no such dependency (the manual path ignores the kill-switch). */ readonly publisher: AsyncLiftPublisher & AsyncLiftDetailedRetrier; readonly stop: () => Promise; } type PublishEncryptionFactory = (publishOptions: PublishOptions) => Promise | undefined> | Pick | undefined; /** Resolve the operator maintenance switch once at a CLI/daemon boundary. */ export declare function resolvePublisherStartPaused(value: string | undefined): boolean; /** * r4 (🟡 3872361426) — the runner's scheduling knobs and error sink travel the construction * chain as ONE value with the runner's own field names, resolved once at each production * boundary (daemon config, standalone CLI args) and spread intact into `new AsyncLiftRunner`. * A knob added to this Pick reaches the runner without touching any intermediate factory — * the per-field relay this replaces is how configured knobs got dropped silently (#1836). */ export type PublisherRunnerSchedulingOptions = Pick; export declare function startPublisherRuntimeIfEnabled(args: { dataDir: string; config: DkgConfig; store: TripleStore; keypair: Ed25519Keypair; chainBase?: RuntimeEvmChainConfig; /** Borrow the agent adapter's current one-log generation; never ownership. */ chainEventLogBindingSource?: ChainEventLogBindingSource; log: (message: string) => void; ackTransportFactory?: ACKTransportFactory; publishEncryptionFactory?: PublishEncryptionFactory; knowledgeAssetVmPublishHandler?: AsyncLiftPublisherConfig['knowledgeAssetVmPublishHandler']; publicSnapshotStore?: WorkspacePublicSnapshotStore; startupSignal?: AbortSignal; }): Promise; export type PublisherStartupOutcome = { runtime: PublisherRuntime; availability: Extract; } | { runtime: null; availability: PublisherDisabledAvailability; } | { runtime: null; availability: NoPublisherWalletsAvailability; } | { runtime: null; availability: PublisherStartupFailedAvailability; error: unknown; }; export type PublisherState = PublisherStartupOutcome | { runtime: null; availability: PublisherStartingAvailability; }; /** * Initial daemon state before the deferred publisher bootstrap settles. Routes * receive this whole discriminated value, so runtime and readiness cannot * disagree in a request context. */ export declare function createInitialPublisherState(config: DkgConfig): PublisherState; /** * Explicit daemon-startup boundary. The compatibility helper above retains its * historical nullable return, while lifecycle code consumes this discriminant * and never has to guess which unavailable state a null runtime represents. */ export declare function startPublisherRuntimeWithOutcome(args: Parameters[0]): Promise; export declare function createPublisherRuntime(args: { dataDir: string; config: DkgConfig; pollIntervalMs?: number; errorBackoffMs?: number; recoveryIntervalMs?: number; activeRecoveryIntervalMs?: number; maxRetries?: number; }): Promise; export declare function createPublisherInspector(args: { dataDir: string; config: DkgConfig; }): Promise; export declare function createPublisherInspectorFromStore(store: TripleStore, closeStoreOnStop?: boolean, publicSnapshotStore?: WorkspacePublicSnapshotStore): PublisherInspector; /** * GH#2270 follow-up (🔴 3822987482, 🟡 3823952750) — the admission-to-runtime capability * bridge, as a named function so the seam itself is testable. * * The daemon builds its admission publisher BEFORE the runtime exists, and admission is what * answers "does this held job have an automatic exit". Reading that from the admission instance's * own wiring always said no, because that instance deliberately holds no resolver. This closes * over the late-bound state instead, so it answers `false` until the runtime is up and delegates * to it thereafter — forwarding both the wallet and the operation kind, since the runtime's answer * is per wallet AND per operation. */ /** * GH#2270 follow-up (🔴 3824531105) — the RUNTIME half of the capability bridge, as a named * factory so the production answer is reachable by a test rather than only by booting a daemon. * * This is the one function both sides use: the runtime's own publisher takes it as * `chainProofCapableForWallet`, and the runtime handle exposes it as `canSettleHeldJob` for the * daemon's admission instance to ask. Sharing it by identity is what keeps those two answers from * drifting; exporting it is what lets a test prove the answer is right rather than merely present. */ export declare function createRuntimeRecoveryCapability(chainAdapters: PublisherChainAdapters): (walletId: string, operationKind: 'create' | 'update' | undefined) => boolean; export declare function createAdmissionRecoveryCapabilityProbe(readState: () => { runtime?: { canSettleHeldJob: (w: string, k: 'create' | 'update' | undefined) => boolean; } | null; }): (walletId: string, operationKind: 'create' | 'update' | undefined) => boolean; export declare function createPublisherControlFromStore(store: TripleStore, options?: { publicSnapshotStore?: WorkspacePublicSnapshotStore; maxRetries?: number; /** * GH#2270 — the same knobs the runtime instance gets. This instance runs no * scheduler, but it DERIVES the `retryState` the job-detail routes serve, and that * derivation reads `autoRetryEnabled`: without the knob the route would report a job * as auto-retry-eligible on a node where the operator switched the lane off (#1836). */ retryTuning?: PublisherRetryTuning; /** * GH#2270 follow-up (🔴 3822987482) — the capability oracle for the LIVE runtime. This * instance deliberately holds no resolver, but it is the one that answers admission, so it * must ask the lane that would actually do the work rather than infer from its own wiring. * Late-bound on purpose: the runtime starts after this instance is built. */ chainProofCapableForWallet?: (walletId: string, operationKind: 'create' | 'update' | undefined) => boolean; }): VmPublisherControl; export declare function createPublisherRuntimeFromAgent(args: { dataDir: string; store: TripleStore; keypair: Ed25519Keypair; chainBase?: RuntimeEvmChainConfig; /** Late-bound because the owning adapter may rebuild after Hub rotation. */ chainEventLogBindingSource?: ChainEventLogBindingSource; /** Resolved by the caller's boundary (daemon config or test); passed through intact. */ runnerOptions?: PublisherRunnerSchedulingOptions; maxRetries?: number; retryTuning?: PublisherRetryTuning; config?: Pick; ackTransportFactory?: ACKTransportFactory; v10ACKProviderFactory?: () => PublishOptions['v10ACKProvider']; publishEncryptionFactory?: PublishEncryptionFactory; knowledgeAssetVmPublishHandler?: AsyncLiftPublisherConfig['knowledgeAssetVmPublishHandler']; publicSnapshotStore?: WorkspacePublicSnapshotStore; startPaused?: boolean; startupSignal?: AbortSignal; }): Promise; /** * Bind every named-KA queue lifecycle callback to the wallet that owns the * claimed job. Keeping this as one handler prevents execution, preflight, and * recovery from accidentally selecting different publisher instances. */ export declare function scopeKnowledgeAssetVmPublishHandler(publishers: Map, handler: AsyncLiftPublisherConfig['knowledgeAssetVmPublishHandler']): AsyncLiftPublisherConfig['knowledgeAssetVmPublishHandler']; export declare function createKnowledgeAssetVmPublishRecoveryResolver(adapters: PublisherChainAdapters): AsyncKnowledgeAssetVmPublishRecoveryResolver; export declare function createPublicSnapshotStore(dataDir: string, config?: Pick, options?: { pageIndexStore?: SnapshotPageIndexStore; log?: (message: string) => void; store?: TripleStore; }): WorkspacePublicSnapshotStore | undefined; //# sourceMappingURL=publisher-runner.d.ts.map