/**
 * DM Pairing System
 *
 * OpenClaw-inspired access control for personal AI assistants exposed
 * to messaging platforms.
 *
 * When pairing mode is enabled:
 * 1. Unknown senders receive a pairing code
 * 2. Messages are NOT processed until the owner approves via:
 *    `pairing approve <channel> <code>`
 * 3. Approved senders are stored in a persistent allowlist
 * 4. Approved senders can interact freely until revoked
 *
 * This prevents unauthorized users from consuming API credits
 * or accessing private information through the bot.
 *
 * Usage:
 * ```typescript
 * const pairing = getDMPairing();
 *
 * // Check if a message sender is approved
 * const status = await pairing.checkSender(message);
 *
 * if (status.approved) {
 *   // Process message normally
 * } else {
 *   // Send pairing code to sender
 *   await channel.send({ content: `Pairing code: ${status.code}` });
 * }
 *
 * // Owner approves from CLI
 * pairing.approve('telegram', 'ABC123');
 * ```
 */
import { EventEmitter } from 'events';
import type { ChannelType, InboundMessage } from './index.js';
/**
 * Pairing status for a sender
 */
export interface PairingStatus {
    /** Whether the sender is approved */
    approved: boolean;
    /** Pairing code (if not approved) */
    code?: string;
    /** When the code expires */
    expiresAt?: Date;
    /** Sender info */
    senderId: string;
    /** Channel type */
    channelType: ChannelType;
}
/**
 * An approved sender in the allowlist
 */
export interface ApprovedSender {
    /** Channel type */
    channelType: ChannelType;
    /** Sender ID on the channel */
    senderId: string;
    /** Display name at time of approval */
    displayName?: string;
    /** When approved */
    approvedAt: Date;
    /** Who approved (owner or auto) */
    approvedBy: string;
    /** Notes */
    notes?: string;
}
/**
 * A pending pairing request
 */
export interface PairingRequest {
    /** Pairing code */
    code: string;
    /** Channel type */
    channelType: ChannelType;
    /** Sender ID */
    senderId: string;
    /** Display name */
    displayName?: string;
    /** Message excerpt */
    messageExcerpt?: string;
    /** When the request was created */
    createdAt: Date;
    /** When the code expires */
    expiresAt: Date;
    /** Number of attempts */
    attempts: number;
}
/**
 * DM Pairing configuration
 */
export interface DMPairingConfig {
    /** Enable pairing mode */
    enabled: boolean;
    /** Channels that require pairing (empty = all) */
    pairingChannels: ChannelType[];
    /** Pairing code length */
    codeLength: number;
    /** Code expiry in milliseconds */
    codeExpiryMs: number;
    /** Maximum pending requests */
    maxPending: number;
    /** Maximum attempts before blocking */
    maxAttempts: number;
    /** Block duration after max attempts (ms) */
    blockDurationMs: number;
    /** Path to persist allowlist */
    allowlistPath?: string;
    /** Auto-approve from same session (CLI) */
    autoApproveCli: boolean;
    /** Message to send to unapproved senders */
    pairingMessage: string;
}
export declare const DEFAULT_DM_PAIRING_CONFIG: DMPairingConfig;
export declare class DMPairingManager extends EventEmitter {
    private config;
    private allowlist;
    private pending;
    private blocked;
    constructor(config?: Partial<DMPairingConfig>);
    /**
     * Check if a message sender is approved.
     * If not, generates a pairing code.
     */
    checkSender(message: InboundMessage): Promise<PairingStatus>;
    /**
     * Get the pairing message for an unapproved sender
     */
    getPairingMessage(status: PairingStatus): string;
    /**
     * Approve a sender using a pairing code
     */
    approve(channelType: ChannelType, code: string, approvedBy?: string): ApprovedSender | null;
    /**
     * Directly approve a sender (without pairing code)
     */
    approveDirectly(channelType: ChannelType, senderId: string, approvedBy?: string, displayName?: string): ApprovedSender;
    /**
     * Revoke approval for a sender
     */
    revoke(channelType: ChannelType, senderId: string): boolean;
    /**
     * Check if a channel requires pairing
     */
    requiresPairing(channelType: ChannelType): boolean;
    /**
     * Check if a sender is blocked
     */
    isBlocked(key: string): boolean;
    /**
     * Check if a sender is approved
     */
    isApproved(channelType: ChannelType, senderId: string): boolean;
    /**
     * List all approved senders
     */
    listApproved(): ApprovedSender[];
    /**
     * List approved senders for a channel
     */
    listApprovedForChannel(channelType: ChannelType): ApprovedSender[];
    /**
     * List pending pairing requests
     */
    listPending(): PairingRequest[];
    /**
     * Generate a pairing code
     */
    private generateCode;
    /**
     * Make allowlist key
     */
    private makeAllowlistKey;
    /**
     * Persist allowlist to disk
     */
    persistAllowlist(): Promise<void>;
    /**
     * Load allowlist from disk
     */
    loadAllowlist(): Promise<void>;
    getStats(): {
        enabled: boolean;
        totalApproved: number;
        totalPending: number;
        totalBlocked: number;
        approvedByChannel: Record<string, number>;
    };
    dispose(): void;
}
export declare function getDMPairing(config?: Partial<DMPairingConfig>): DMPairingManager;
export declare function resetDMPairing(): void;
