import { Provider } from '@near-js/providers';
import { SerializedReturnValue, BlockReference, TxExecutionStatus } from '@near-js/types';

interface TcbInfo {
    mrtd: string;
    rtmr0: string;
    rtmr1: string;
    rtmr2: string;
    rtmr3: string;
    os_image_hash: string;
    compose_hash: string;
    device_id: string;
    app_compose: string;
    event_log: EventLog[];
}
interface EventLog {
    imr: number;
    event_type: number;
    digest: string;
    event: string;
    event_payload: string;
}

interface DstackAttestationForContract {
    quote: number[];
    collateral: {
        pck_crl_issuer_chain: string;
        root_ca_crl: string;
        pck_crl: string;
        tcb_info_issuer_chain: string;
        tcb_info: string;
        tcb_info_signature: string;
        qe_identity_issuer_chain: string;
        qe_identity: string;
        qe_identity_signature: string;
    };
    tcb_info: TcbInfo;
}

interface Measurements {
    /** MRTD (Measurement of Root of Trust for Data) - identifies the virtual firmware. */
    mrtd: string;
    /** RTMR0 (Runtime Measurement Register 0) - typically measures the bootloader, virtual firmware data, and configuration. */
    rtmr0: string;
    /** RTMR1 (Runtime Measurement Register 1) - typically measures the OS kernel, boot parameters, and initrd (initial ramdisk). */
    rtmr1: string;
    /** RTMR2 (Runtime Measurement Register 2) - typically measures the OS application. */
    rtmr2: string;
}
interface FullMeasurements {
    /** Expected RTMRs (Runtime Measurement Registers). */
    rtmrs: Measurements;
    /** Expected digest for the key-provider event. */
    key_provider_event_digest: string;
    /** Expected app_compose hash payload. */
    app_compose_hash_payload: string;
}
/**
 * Configuration object for creating a ShadeClient instance
 */
interface ShadeConfig {
    /** Network ID ('testnet' or 'mainnet'), defaults to 'testnet' if not provided */
    networkId?: "testnet" | "mainnet";
    /** The NEAR contract ID for the agent contract */
    agentContractId?: string;
    /** Sponsor account configuration for funding the agent account */
    sponsor?: {
        /** The sponsor's NEAR account ID */
        accountId: string;
        /** The sponsor's private key */
        privateKey: string;
    };
    /** Custom NEAR RPC provider. If not provided, a default provider will be created based on networkId */
    rpc?: Provider;
    /** Number of keys to use for the agent (1-100), defaults to 1 if not provided */
    numKeys?: number;
    /** Derivation path for deterministic key generation for local testing (needs to be a randomly unique string)*/
    derivationPath?: string;
}
declare class ShadeClient {
    private config;
    private dstackClient;
    private agentAccountId;
    private agentPrivateKeys;
    private currentKeyIndex;
    private keysDerivedWithTEE;
    private keysChecked;
    private constructor();
    /**
     * Creates a new ShadeClient instance asynchronously
     * @param config - Configuration object for the Shade client (see ShadeConfig interface for details)
     * @returns Promise that resolves to a ShadeClient instance
     * @throws Error if configuration is invalid, network ID mismatch, or key generation fails
     */
    static create(config: ShadeConfig): Promise<ShadeClient>;
    /**
     * Gets the NEAR account ID of the agent
     * @returns The agent's account ID
     */
    accountId(): string;
    /**
     * Gets the NEAR balance of the agent account in human readable format (e.g. 1 = one NEAR)
     * @returns Promise that resolves to the account balance in NEAR tokens, if the agent account does not exist, returns 0
     * @throws Error if network request fails
     */
    balance(): Promise<number>;
    /**
     * Registers the agent in the agent contract.
     *
     * @param params
     * @param params.deposit Attached deposit in yoctoNEAR when storage is required or when `forceDeposit` is `true` (defaults to `5000000000000000000000` — 0.005 NEAR)
     * @param params.forceDeposit If `true`, always attach `deposit` (or the default) and skip `get_agent`. If `false`, attach no deposit and skip `get_agent`. If omitted, use `get_agent` to decide.
     * @returns Promise that resolves to true if registration was successful
     * @throws Error if agentContractId is not configured, if fetching attestation fails, or if the contract call fails
     */
    register(params?: {
        deposit?: bigint | string | number;
        forceDeposit?: boolean;
    }): Promise<boolean>;
    /**
     * Call a view function on the agent contract and return the result
     * @param params
     * @param params.methodName The method that will be called
     * @param params.args Arguments as a valid JSON Object
     * @param params.blockQuery (optional) Block reference for the query
     * @returns A promise that resolves with the result of the view function call
     * @throws Error if agentContractId is not configured or if RPC call fails
     */
    view<T extends SerializedReturnValue>(params: {
        methodName: string;
        args: Record<string, unknown>;
        blockQuery?: BlockReference;
    }): Promise<T>;
    /**
     * Call a function on the agent contract and return the result
     * @param params
     * @param params.methodName The method that will be called
     * @param params.args Arguments, either as a valid JSON Object or a raw Uint8Array
     * @param params.deposit (optional) Amount of NEAR Tokens to attach to the call
     * @param params.gas (optional) Amount of GAS to use attach to the call
     * @param params.waitUntil (optional) Transaction finality to wait for
     * @returns A promise that resolves with the result of the contract function call
     * @throws Error if agentContractId is not configured, if key derivation fails, or if transaction fails
     */
    call<T extends SerializedReturnValue>(params: {
        methodName: string;
        args: Uint8Array | Record<string, any>;
        deposit?: bigint | string | number;
        gas?: bigint | string | number;
        waitUntil?: TxExecutionStatus;
    }): Promise<T>;
    /**
     * Gets the TEE attestation for the agent in contract format (ready to be sent to the contract)
     * @returns Promise that resolves to the contract-formatted attestation object
     * @throws Error if fetching quote collateral fails (network errors, HTTP errors, timeouts)
     */
    getAttestation(): Promise<DstackAttestationForContract>;
    /**
     * Funds the agent account with NEAR tokens from the sponsor account
     * @param fundAmount - Amount of NEAR tokens to transfer to the agent account in human readable format (e.g. 1 = one NEAR)
     * @returns Promise that resolves when funding is complete
     * @throws Error if sponsor is not configured or if transfer fails after retries
     */
    fund(fundAmount: number): Promise<void>;
    /**
     * Gets the agent's private keys (use with caution)
     * @param params - Must pass `{ acknowledgeRisk: true }`
     * @returns Array of private key strings
     */
    getPrivateKeys(params: {
        acknowledgeRisk: true;
    }): string[];
    /**
     * Checks if the agent is whitelisted for local mode
     * @returns Promise that resolves to true if the agent is whitelisted, false if the agent is not whitelisted, or null if the agent contract requires TEE
     * @throws Error if agentContractId is not configured or if view call fails
     */
    isWhitelisted(): Promise<boolean | null>;
}

/**
 * Sanitization utilities to prevent private key leaks in error messages and logs.
 */
/**
 * Sanitizes any value: strings, objects, Errors, and primitives.
 * Redacts private key patterns and sensitive keys (privateKey, secretKey, etc.).
 * Returns values that cannot contain a private key as-is.
 *
 * - string → sanitized string
 * - Error → new Error with sanitized message
 * - object/array → redacted copy
 * - null/undefined/number/boolean/symbol/bigint → returned as-is
 */
declare function sanitize(value: unknown): unknown;
/** Returns an Error suitable for throwing. Use: throw toThrowable(caughtError) */
declare function toThrowable(error: unknown): Error;

export { type DstackAttestationForContract, type FullMeasurements, type Measurements, ShadeClient, type ShadeConfig, sanitize, toThrowable };
