import type { Bip44Account } from "@metamask/account-api";
import type { TraceCallback, TraceRequest } from "@metamask/controller-utils";
import type { SnapKeyring as SnapKeyringV2 } from "@metamask/eth-snap-keyring/v2";
import type { CreateAccountBip44DeriveIndexOptions, CreateAccountBip44DeriveIndexRangeOptions, CreateAccountBip44DiscoverOptions, CreateAccountOptions, EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
import type { KeyringCapabilities } from "@metamask/keyring-api/v2";
import type { InternalAccount } from "@metamask/keyring-internal-api";
import type { SnapId } from "@metamask/snaps-sdk";
import type { CaipChainId } from "@metamask/utils";
import type { MultichainAccountServiceMessenger } from "../types.cjs";
import { BaseBip44AccountProvider } from "./BaseBip44AccountProvider.cjs";
import type { SnapKeyringClient } from "./SnapKeyringClient.cjs";
/**
 * A proxy to the Snap's keyring operations that routes every call through the
 * `KeyringController` mutex (via {@link SnapAccountProvider.#withSnapKeyring}).
 * Callers receive this object from {@link SnapAccountProvider.withSnap} and
 * never interact with the raw keyring or the mutex directly.
 */
export type SnapKeyringProxy = {
    createAccounts: SnapKeyringV2['createAccounts'];
    deleteAccount: SnapKeyringV2['deleteAccount'];
};
export type SnapAccountProviderConfig = {
    maxConcurrency?: number;
    discovery: {
        enabled?: boolean;
        maxAttempts: number;
        timeoutMs: number;
        backOffMs: number;
    };
    createAccounts: {
        /**
         * Timeout for account creation operations.
         *
         * NOTE: Batching (and thus whether a single call may create multiple
         * accounts) is driven by the Snap's declared capabilities, not this config.
         * The value might have to be adapted when the Snap supports batching.
         */
        timeoutMs: number;
    };
    resyncAccounts?: {
        /**
         * Whether to automatically remove extra Snap accounts when the Snap has
         * more accounts than MetaMask. If `false`, a warning is logged instead.
         * Defaults to `true`.
         */
        autoRemoveExtraSnapAccounts?: boolean;
    };
};
export declare abstract class SnapAccountProvider extends BaseBip44AccountProvider {
    #private;
    readonly snapId: SnapId;
    protected readonly config: SnapAccountProviderConfig;
    /**
     * The Snap's keyring capabilities, sourced from `SnapAccountService` (which
     * reads them from the Snap's manifest). Populated the first time the client
     * is resolved; defaults to an empty capability set until then.
     */
    capabilities: KeyringCapabilities;
    /**
     * Scopes passed to the v1 `discoverAccounts` client method. Only used on the
     * v1 discovery path.
     *
     * TODO: Remove once all Snaps are fully v2 — discovery is then driven by the
     * Snap's own supported scopes via `createAccounts({ bip44:discover })`.
     */
    protected abstract readonly v1DiscoveryScopes: CaipChainId[];
    constructor(snapId: SnapId, messenger: MultichainAccountServiceMessenger, config: SnapAccountProviderConfig, trace?: TraceCallback);
    /**
     * Ensures that the Snap is ready to be used.
     *
     * Once this resolves, a Snap keyring for {@link snapId} is guaranteed to
     * exist in the `KeyringController`, so subsequent {@link #withSnapKeyring}
     * calls will not fail with "No keyring matches the selector".
     *
     * @returns A promise that resolves when the Snap is ready.
     * @throws An error if the Snap could not become ready.
     */
    ensureReady(): Promise<void>;
    /**
     * Wraps an async operation with concurrency limiting based on maxConcurrency config.
     * If maxConcurrency is Infinity (the default), the operation runs immediately without throttling.
     * Otherwise, it's queued through the semaphore to respect the concurrency limit.
     *
     * @param operation - The async operation to execute.
     * @returns The result of the operation.
     */
    protected withMaxConcurrency<Result>(operation: () => Promise<Result>): Promise<Result>;
    protected trace<ReturnType>(request: TraceRequest, fn: () => Promise<ReturnType>): Promise<ReturnType>;
    /**
     * Whether the Snap supports the v2 keyring protocol, inferred from its
     * declared capabilities (a v2-capable Snap declares BIP-44 capabilities).
     *
     * @returns `true` if the Snap is v2-capable.
     */
    protected isV2(): boolean;
    resyncAccounts(accounts: Bip44Account<InternalAccount>[]): Promise<void>;
    protected withSnap<CallbackResult = void>(operation: (snap: {
        client: SnapKeyringClient;
        keyring: SnapKeyringProxy;
    }) => Promise<CallbackResult>): Promise<CallbackResult>;
    abstract isAccountCompatible(account: Bip44Account<InternalAccount>): boolean;
    protected toBip44Account(account: KeyringAccount, _options: {
        entropySource: EntropySourceId;
        groupIndex: number;
    }): Bip44Account<KeyringAccount>;
    protected createBip44Accounts(keyring: SnapKeyringProxy, options: CreateAccountBip44DeriveIndexOptions | CreateAccountBip44DeriveIndexRangeOptions | CreateAccountBip44DiscoverOptions): Promise<Bip44Account<KeyringAccount>[]>;
    createAccounts(options: CreateAccountOptions): Promise<Bip44Account<KeyringAccount>[]>;
    /**
     * Delete a snap account by id.
     *
     * Resolves the account's address from the tracked account, then forwards to
     * the legacy `SnapKeyring.removeAccount(address)`. The Snap keyring takes
     * care of notifying the snap to clean up its own state through the normal
     * account-removal flow (same path used by `resyncAccounts`).
     *
     * @param id - The id of the account to delete.
     */
    deleteAccount(id: Bip44Account<KeyringAccount>['id']): Promise<void>;
    /**
     * Discovers accounts for the given entropy source and group index.
     *
     * v2 Snaps drive discovery through `createAccounts({ bip44:discover })`: the
     * Snap checks for on-chain activity (using its own supported scopes) and
     * returns the created account(s), or nothing once discovery is exhausted.
     *
     * v1 Snaps use the client's `discoverAccounts` to detect activity on
     * {@link v1DiscoveryScopes}, then create the account for the group index.
     *
     * @param options - The discovery options.
     * @param options.entropySource - The entropy source to discover accounts for.
     * @param options.groupIndex - The group index to discover accounts for.
     * @returns The discovered (and created) accounts, or an empty array when
     * there is nothing to discover at this group index.
     */
    discoverAccounts({ entropySource, groupIndex, }: {
        entropySource: EntropySourceId;
        groupIndex: number;
    }): Promise<Bip44Account<KeyringAccount>[]>;
}
export declare const isSnapAccountProvider: (provider: unknown) => provider is SnapAccountProvider;
//# sourceMappingURL=SnapAccountProvider.d.cts.map