import { PopulatedTransaction } from 'ethers';
import { Logger } from 'pino';
import { StaticAggregationHookFactory } from '@hyperlane-xyz/core';
import { Address } from '@hyperlane-xyz/utils';
import { MultiProvider } from '../providers/MultiProvider.js';
import { TokenType } from '../token/config.js';
import { PredicateWrapperConfig } from '../token/types.js';
import { ChainName } from '../types.js';
export interface PredicateWrapperDeploymentResult {
    wrapperAddress: Address;
    aggregationHookAddress: Address;
    setHookTx: PopulatedTransaction;
}
export declare class PredicateWrapperDeployer {
    private readonly multiProvider;
    private readonly staticAggregationHookFactory;
    private readonly logger;
    constructor(multiProvider: MultiProvider, staticAggregationHookFactory: StaticAggregationHookFactory, logger?: Logger);
    deployPredicateWrapper(chain: ChainName, warpRouteAddress: Address, config: PredicateWrapperConfig, tokenType?: TokenType): Promise<Address>;
    createAggregationHook(chain: ChainName, predicateWrapperAddress: Address, existingHookAddress: Address): Promise<Address>;
    /**
     * Deploys the predicate wrapper and aggregation hook on-chain as a side effect, then
     * returns the populated setHook transaction for the caller to include in its transaction
     * array.
     *
     * IMPORTANT — irreversible side effects: deployPredicateWrapper submits a real on-chain
     * transaction before this method returns. If the caller discards the returned setHookTx
     * (dry-run, cancellation, error), the PredicateRouterWrapper is orphaned — deployed but
     * unreferenced by any warp route. The aggregation hook is safe because
     * StaticAggregationHookFactory uses CREATE2 (idempotent). Eliminating the wrapper orphan
     * risk requires a CREATE2 factory for PredicateRouterWrapper (future contract work).
     *
     * This differs from EvmHookModule/EvmIsmModule: those modules own the full configuration
     * lifecycle (deploy + configure in one atomic step). Here, deployment is eager but the
     * final wiring (setHook) is deferred to EvmWarpModule.update(), which may choose not to
     * submit it.
     *
     * @param existingHookOverride - When provided, skips the on-chain hook() read and uses
     *   this address instead. Pass the pending new hook address when a hook update is being
     *   applied in the same update() call to avoid wrapping a stale on-chain hook.
     */
    deployAndConfigure(chain: ChainName, warpRouteAddress: Address, config: PredicateWrapperConfig, tokenType?: TokenType, existingHookOverride?: Address): Promise<PredicateWrapperDeploymentResult>;
    /**
     * If hookAddress is a StaticAggregationHook that contains a predicate wrapper,
     * strips it and (when multiple non-predicate sub-hooks remain) re-aggregates
     * them via CREATE2 before returning, so the caller can safely wrap the result
     * in a new aggregation without stacking wrappers.
     *
     * Falls back to hookAddress unchanged when:
     * - The address is zero / not an aggregation hook
     * - No predicate wrapper is found among sub-hooks
     * - Multiple non-predicate sub-hooks remain (cannot safely re-aggregate here)
     */
    private stripPredicateAndReaggregateHook;
}
//# sourceMappingURL=PredicateDeployer.d.ts.map