/** * Validator High Availability Signer * * Wraps signing operations with distributed locking and slashing protection. * This ensures that even with multiple validator nodes running, only one * node will sign for a given duty (slot + duty type). */ import type { Buffer32 } from '@aztec/foundation/buffer'; import { EthAddress } from '@aztec/foundation/eth-address'; import type { Signature } from '@aztec/foundation/eth-signature'; import { type DateProvider } from '@aztec/foundation/timer'; import { type BaseSignerConfig, type HAProtectedSigningContext } from '@aztec/stdlib/ha-signing'; import type { HASignerMetrics } from './metrics.js'; import type { SlashingProtectionDatabase } from './types.js'; export interface ValidatorHASignerDeps { metrics: HASignerMetrics; dateProvider: DateProvider; } /** * Validator High Availability Signer * * Provides signing capabilities with distributed locking for validators * in a high-availability setup. * * Usage: * ``` * const signer = new ValidatorHASigner(db, config); * * // Sign with slashing protection * const signature = await signer.signWithProtection( * validatorAddress, * messageHash, * { slot: 100n, blockNumber: 50n, dutyType: 'BLOCK_PROPOSAL' }, * async (root) => localSigner.signMessage(root), * ); * ``` */ export declare class ValidatorHASigner { private readonly config; private readonly log; private readonly slashingProtection; private readonly rollupAddress; private readonly dateProvider; private readonly metrics; private readonly signerCallTimeoutMs; constructor(db: SlashingProtectionDatabase, config: BaseSignerConfig, deps: ValidatorHASignerDeps); /** * Sign a message with slashing protection. * * This method: * 1. Acquires a distributed lock for (validator, slot, dutyType) * 2. Calls the provided signing function * 3. Records the result (success or failure) * * @param validatorAddress - The validator's Ethereum address * @param messageHash - The hash to be signed * @param context - The signing context (HA-protected duty types only) * @param signFn - Function that performs the actual signing * @returns The signature * * @throws DutyAlreadySignedError if the duty was already signed (expected in HA) * @throws SlashingProtectionError if attempting to sign different data for same slot (expected in HA) */ signWithProtection(validatorAddress: EthAddress, messageHash: Buffer32, context: HAProtectedSigningContext, signFn: (messageHash: Buffer32) => Promise): Promise; /** * Get the node ID for this signer */ get nodeId(): string; /** * Start the HA signer background tasks (cleanup of stuck duties). * Should be called after construction and before signing operations. */ start(): Promise; /** * Stop the HA signer background tasks and close database connection. * Should be called during graceful shutdown. */ stop(): Promise; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9yX2hhX3NpZ25lci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3ZhbGlkYXRvcl9oYV9zaWduZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBQ0gsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDekQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWpFLE9BQU8sRUFBRSxLQUFLLFlBQVksRUFBa0IsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RSxPQUFPLEVBQ0wsS0FBSyxnQkFBZ0IsRUFFckIsS0FBSyx5QkFBeUIsRUFHL0IsTUFBTSwwQkFBMEIsQ0FBQztBQUlsQyxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFcEQsT0FBTyxLQUFLLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFN0QsTUFBTSxXQUFXLHFCQUFxQjtJQUNwQyxPQUFPLEVBQUUsZUFBZSxDQUFDO0lBQ3pCLFlBQVksRUFBRSxZQUFZLENBQUM7Q0FDNUI7QUFLRDs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gscUJBQWEsaUJBQWlCO0lBVzFCLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTTtJQVZ6QixPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBUztJQUM3QixPQUFPLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUE0QjtJQUMvRCxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBYTtJQUUzQyxPQUFPLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBZTtJQUM1QyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBa0I7SUFDMUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBUztJQUU3QyxZQUNFLEVBQUUsRUFBRSwwQkFBMEIsRUFDYixNQUFNLEVBQUUsZ0JBQWdCLEVBQ3pDLElBQUksRUFBRSxxQkFBcUIsRUFpQzVCO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7T0FnQkc7SUFDRyxrQkFBa0IsQ0FDdEIsZ0JBQWdCLEVBQUUsVUFBVSxFQUM1QixXQUFXLEVBQUUsUUFBUSxFQUNyQixPQUFPLEVBQUUseUJBQXlCLEVBQ2xDLE1BQU0sRUFBRSxDQUFDLFdBQVcsRUFBRSxRQUFRLEtBQUssT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUNwRCxPQUFPLENBQUMsU0FBUyxDQUFDLENBMkVwQjtJQUVEOztPQUVHO0lBQ0gsSUFBSSxNQUFNLElBQUksTUFBTSxDQUVuQjtJQUVEOzs7T0FHRztJQUNHLEtBQUssa0JBRVY7SUFFRDs7O09BR0c7SUFDRyxJQUFJLGtCQUdUO0NBQ0YifQ==