import type { Address } from 'viem';
import type { Hex } from 'viem';
import type { Prettify } from 'viem/chains';
import type { RpcSchema } from 'viem';
import type { SiweMessage } from 'viem/siwe';

/**
 * Decode a base64url encoded string
 * @param value The value to decode
 * @returns The decoded value
 */
export declare function base64urlDecode(value: string): Uint8Array;

/**
 * Encode a buffer to a base64url encoded string
 * @param buffer The buffer to encode
 * @returns The encoded string
 */
export declare function base64urlEncode(buffer: Uint8Array): string;

/**
 * Base props for the iframe
 * @ignore
 */
export declare const baseIframeProps: {
    id: string;
    name: string;
    title: string;
    allow: string;
    style: {
        width: string;
        height: string;
        border: string;
        position: string;
        zIndex: number;
        top: string;
        left: string;
        colorScheme: string;
    };
};

/**
 * Event related to the iframe lifecycle
 * @ignore
 */
export declare type ClientLifecycleEvent = CustomCssEvent | CustomI18nEvent | RestoreBackupEvent | HearbeatEvent | HandshakeResponse;

/** @ignore */
export declare class ClientNotFound extends FrakRpcError {
    constructor();
}

/**
 * Compress the current Frak context
 * @param context - The context to be compressed
 * @returns A compressed string containing the Frak context
 */
declare function compress(context?: Partial<FrakContext>): string | undefined;

/**
 * The received encoded data from a client
 *  -> The encoded should contain a HashProtectedData once decoded
 *  @ignore
 */
export declare type CompressedData = Uint8Array;

/**
 * Compress json data
 * @param data
 * @ignore
 */
export declare function compressJson(data: unknown): Uint8Array;

/**
 * Compress json data
 * @param data
 * @ignore
 */
export declare function compressJsonToB64(data: unknown): string;

/**
 * Create the Frak iframe
 * @param args
 * @param args.walletBaseUrl - Use `config.walletUrl` instead. Will be removed in future versions.
 * @param args.config - The configuration object containing iframe options, including the replacement for `walletBaseUrl`.
 */
export declare function createIframe({ walletBaseUrl, config, }: {
    walletBaseUrl?: string;
    config?: FrakWalletSdkConfig;
}): Promise<HTMLIFrameElement | undefined>;

/**
 * Create a new iframe Frak client
 * @param args
 * @param args.config - The configuration to use for the Frak Wallet SDK
 * @param args.iframe - The iframe to use for the communication
 * @returns The created Frak Client
 *
 * @example
 * const frakConfig: FrakWalletSdkConfig = {
 *     metadata: {
 *         name: "My app title",
 *     },
 * }
 * const iframe = await createIframe({ config: frakConfig });
 * const client = createIFrameFrakClient({ config: frakConfig, iframe });
 */
export declare function createIFrameFrakClient({ config, iframe, }: {
    config: FrakWalletSdkConfig;
    iframe: HTMLIFrameElement;
}): FrakClient;

/**
 * All the currencies available
 * @category Config
 */
export declare type Currency = "eur" | "usd" | "gbp";

declare type CustomCssEvent = {
    clientLifecycle: "modal-css";
    data: {
        cssLink: string;
    };
};

declare type CustomI18nEvent = {
    clientLifecycle: "modal-i18n";
    data: {
        i18n: I18nConfig;
    };
};

/** @ignore */
export declare class DebugInfoGatherer {
    private config?;
    private iframe?;
    private isSetupDone;
    private lastResponse;
    private lastRequest;
    constructor(config?: FrakWalletSdkConfig, iframe?: HTMLIFrameElement);
    setLastResponse(event: MessageEvent<IFrameEvent>): void;
    setLastRequest(event: IFrameEvent, target: string): void;
    updateSetupStatus(status: boolean): void;
    private base64Encode;
    /**
     * Extract information from the iframe status
     */
    private getIframeStatus;
    private getNavigatorInfo;
    private gatherDebugInfo;
    static empty(): DebugInfoGatherer;
    /**
     * Format Frak debug information
     */
    formatDebugInfo(error: Error | unknown | string): string;
}

/**
 * Decompress the given Frak context
 * @param context - The raw context to be decompressed into a `FrakContext`
 * @returns The decompressed Frak context, or undefined if it fails
 */
declare function decompress(context?: string): FrakContext | undefined;

/**
 * Decompress the given string
 * @param compressedData The params to encode
 * @ignore
 */
export declare function decompressDataAndCheckHash<T>(compressedData: CompressedData): HashProtectedData<T>;

/**
 * Decompress json data
 * @param data
 * @ignore
 */
export declare function decompressJson<T>(data: Uint8Array): T | null;

/**
 * Decompress json data
 * @param data
 * @ignore
 */
export declare function decompressJsonFromB64<T>(data: string): T | null;

/**
 * Simple deferred promise wrapper
 * @ignore
 */
export declare class Deferred<T> {
    private readonly _promise;
    private _resolve;
    private _reject;
    constructor();
    get promise(): Promise<T>;
    resolve: (value: T | PromiseLike<T>) => void;
    reject: (reason?: unknown) => void;
}

/**
 * The params used to display the embedded wallet
 *
 * @group Embedded wallet
 */
export declare type DisplayEmbeddedWalletParamsType = {
    /**
     * The embedded view to display once the user is logged in
     */
    loggedIn?: LoggedInEmbeddedView;
    /**
     * The embedded view to display once the user is logged out
     */
    loggedOut?: LoggedOutEmbeddedView;
    /**
     * Some metadata to customize the embedded view
     */
    metadata?: {
        /**
         * The logo to display on the embedded wallet
         * If undefined, will default to no logo displayed
         */
        logo?: string;
        /**
         * Link to the homepage of the calling website
         * If undefined, will default to the domain of the calling website
         */
        homepageLink?: string;
        /**
         * The target interaction behind this modal
         */
        targetInteraction?: FullInteractionTypesKey;
        /**
         * The position of the component
         */
        position?: "left" | "right";
        /**
         * Some i18n override for the displayed modal (i.e. update the displayed text only for this modal)
         */
        i18n?: I18nConfig;
    };
};

/**
 * The result of the display embedded wallet rpc request
 *
 * @group Embedded wallet
 */
export declare type DisplayEmbeddedWalletResultType = {
    wallet: Address;
};

/**
 * Params used to display a modal
 * @typeParam T - The list of modal steps we expect to have in the modal
 * @group Modal Display
 */
export declare type DisplayModalParamsType<T extends ModalStepTypes[]> = {
    steps: ModalRpcStepsInput<T>;
    metadata?: ModalRpcMetadata;
};

declare type DoBackupEvent = {
    iframeLifecycle: "do-backup";
    data: {
        backup?: string;
    };
};

/**
 * The action to display on the logged out embedded view when the user is referred
 *
 * @group Embedded wallet
 */
export declare type EmbeddedViewActionReferred = {
    key: "referred";
    /**
     * No options for a referred action
     */
    options?: never;
};

/**
 * The different type of action we can have on the embedded view (once the user is logged in)
 *
 * @group Embedded wallet
 */
export declare type EmbeddedViewActionSharing = {
    key: "sharing";
    /**
     * Some sharing options
     */
    options?: {
        /**
         * The title that will be displayed on the system popup once the system sharing window is open
         * @deprecated Use the top level `config.metadata.i18n` instead
         */
        popupTitle?: string;
        /**
         * The text that will be shared alongside the link.
         * Can contain the variable {LINK} to specify where the link is placed, otherwise it will be added at the end
         * @deprecated Use the top level `config.metadata.i18n` instead
         */
        text?: string;
        /**
         * The link to be shared (will be suffixed with the Frak sharing context)
         */
        link?: string;
    };
};

/**
 * Type that extract the possible return type from a RPC Schema
 * @ignore
 */
declare type ExtractedMethodFromRpc<TRpcSchema extends RpcSchema, TMethod extends ExtractedParametersFromRpc<TRpcSchema>["method"] = ExtractedParametersFromRpc<TRpcSchema>["method"]> = Extract<TRpcSchema[number], {
    Method: TMethod;
}>;

/**
 * Type that extract the possible parameters from a RPC Schema
 * @ignore
 */
export declare type ExtractedParametersFromRpc<TRpcSchema extends RpcSchema> = {
    [K in keyof TRpcSchema]: Prettify<{
        method: TRpcSchema[K] extends TRpcSchema[number] ? TRpcSchema[K]["Method"] : string;
    } & (TRpcSchema[K] extends TRpcSchema[number] ? TRpcSchema[K]["Parameters"] extends undefined ? {
        params?: never;
    } : {
        params: TRpcSchema[K]["Parameters"];
    } : never)>;
}[number];

/**
 * Type that extract the possible return type from a RPC Schema
 * @ignore
 */
export declare type ExtractedReturnTypeFromRpc<TRpcSchema extends RpcSchema, TParameters extends ExtractedParametersFromRpc<TRpcSchema> = ExtractedParametersFromRpc<TRpcSchema>> = ExtractedMethodFromRpc<TRpcSchema, TParameters["method"]>["ReturnType"];

/**
 * The different types of final actions we can display in the final step
 * @group Modal Display
 */
export declare type FinalActionType = {
    key: "sharing";
    options?: {
        /**
         * @deprecated Use the top level `config.metadata.i18n` instead
         */
        popupTitle?: string;
        /**
         * @deprecated Use the top level `config.metadata.i18n` instead
         */
        text?: string;
        link?: string;
    };
} | {
    key: "reward";
    options?: never;
};

/**
 * The final modal step type, could be used to display sharing options or a success reward screen.
 *
 * **Input**: What type final step to display?
 * **Output**: None
 *
 * @group Modal Display
 */
export declare type FinalModalStepType = GenericModalStepType<"final", {
    dismissedMetadata?: ModalStepMetadata["metadata"];
    action: FinalActionType;
    autoSkip?: boolean;
}, object>;

export declare function formatAmount(amount: number, currency?: Currency): string;

/**
 * Representing a Frak client, used to interact with the Frak Wallet
 */
export declare type FrakClient = {
    config: FrakWalletSdkConfig;
    debugInfo: {
        formatDebugInfo: (error: Error | unknown | string) => string;
    };
} & IFrameTransport;

/**
 * The current Frak Context
 *
 * For now, only contain a referrer address.
 *
 * @ignore
 */
export declare type FrakContext = {
    r: Address;
};

/**
 * Export our frak context "class"
 */
export declare const FrakContextManager: {
    compress: typeof compress;
    decompress: typeof decompress;
    parse: typeof parse;
    update: typeof update;
    remove: typeof remove;
    replaceUrl: typeof replaceUrl;
};

/**
 * Generic Frak RPC error
 * @ignore
 */
export declare class FrakRpcError<T = undefined> extends Error {
    code: number;
    data?: T | undefined;
    constructor(code: number, message: string, data?: T | undefined);
}

/**
 * Configuration for the Frak Wallet SDK
 * @category Config
 */
export declare type FrakWalletSdkConfig = {
    /**
     * The Frak wallet url
     * @defaultValue "https://wallet.frak.id"
     */
    walletUrl?: string;
    /**
     * Some metadata about your implementation of the Frak SDK
     */
    metadata: {
        /**
         * Your application name (will be displayed in a few modals and in SSO)
         */
        name: string;
        /**
         * Language to display in the modal
         * If undefined, will default to the browser language
         */
        lang?: Language;
        /**
         * The currency to display in the modal
         * @defaultValue `"eur"`
         */
        currency?: Currency;
        /**
         * The logo URL that will be displayed in a few components
         */
        logoUrl?: string;
        /**
         * The homepage link that could be displayed in a few components
         */
        homepageLink?: string;
    };
    /**
     * Some customization for the modal
     */
    customizations?: {
        /**
         * Custom CSS styles to apply to the modals and components
         */
        css?: `${string}.css`;
        /**
         * Custom i18n configuration for the modal
         */
        i18n?: I18nConfig;
    };
    /**
     * The domain name of your application
     * @defaultValue window.location.host
     */
    domain?: string;
};

/**
 * The keys for each interaction types (e.g. `press.openArticle`) -> category_type.interaction_type
 * @inline
 */
export declare type FullInteractionTypesKey = {
    [Category in keyof typeof interactionTypes]: `${Category & string}.${keyof (typeof interactionTypes)[Category] & string}`;
}[keyof typeof interactionTypes];

/**
 * Represent a generic modal step type
 * @ignore
 * @inline
 */
declare type GenericModalStepType<TKey, TParams, TReturns> = {
    key: TKey;
    params: TParams extends never ? ModalStepMetadata : ModalStepMetadata & TParams;
    returns: TReturns;
};

/**
 * Get the currency amount key for a given currency
 * @param currency - The currency to use
 * @returns The currency amount key
 */
export declare function getCurrencyAmountKey(currency?: Currency): keyof TokenAmountType;

/**
 * Response of the `frak_getProductInformation` RPC method
 * @group RPC Schema
 */
export declare type GetProductInformationReturnType = {
    /**
     * Current product id
     */
    id: Hex;
    /**
     * Some metadata
     */
    onChainMetadata: {
        /**
         * Name of the product on-chain
         */
        name: string;
        /**
         * Domain of the product on-chain
         */
        domain: string;
        /**
         * The supported product types
         */
        productTypes: ProductTypesKey[];
    };
    /**
     * The max potential reward for the referrer
     */
    maxReferrer?: TokenAmountType;
    /**
     * The max potential reward for the referee
     */
    maxReferee?: TokenAmountType;
    /**
     * List of all the potentials reward arround this product
     */
    rewards: {
        token: Address;
        campaign: Address;
        interactionTypeKey: FullInteractionTypesKey;
        referrer: TokenAmountType;
        referee: TokenAmountType;
    }[];
};

/**
 * Get the supported currency for a given currency
 * @param currency - The currency to use
 * @returns The supported currency
 */
export declare function getSupportedCurrency(currency?: Currency): Currency;

/**
 * Get the supported locale for a given currency
 * @param currency - The currency to use
 * @returns The supported locale
 */
export declare function getSupportedLocale(currency?: Currency): (typeof locales)[LocalesKey];

declare type HandshakeRequestEvent = {
    iframeLifecycle: "handshake";
    data: {
        token: string;
    };
};

declare type HandshakeResponse = {
    clientLifecycle: "handshake-response";
    data: {
        token: string;
        currentUrl: string;
    };
};

/**
 * Compress the given params, and add hash protection to (rapidly) prevent interception modification
 * @param data The params to encode
 * @ignore
 */
export declare function hashAndCompressData<T>(data: T): CompressedData;

/**
 * The encoded data to send to a client / received by a client
 *  @ignore
 */
export declare type HashProtectedData<DataType> = Readonly<DataType & {
    validationHash: string;
}>;

declare type HearbeatEvent = {
    clientLifecycle: "heartbeat";
};

/**
 * Custom i18n configuration for the modal
 *  See [i18next json format](https://www.i18next.com/misc/json-format#i18next-json-v4)
 *
 * Available variables
 *  - `{{ productName }}` : The name of your website (`metadata.name`)
 *  - `{{ productOrigin }}` : The origin url of your website
 *  - `{{ estimatedReward }}` : The estimated reward for the user (based on the specific `targetInteraction` you can specify, or the max referrer reward if no target interaction is specified)
 *
 * Context of the translation [see i18n context](https://www.i18next.com/translation-function/context)
 *  - For modal display, the key of the final action (`sharing`, `reward`, or undefined)
 *  - For embedded wallet display, the key of the logged in action (`sharing` or undefined)
 *
 * @example
 * ```ts
 * // Multi language config
 * const multiI18n = {
 *  fr: {
 *      "sdk.modal.title": "Titre de modal",
 *      "sdk.modal.description": "Description de modal, avec {{ estimatedReward }} de gains possible",
 *  },
 *  en: "https://example.com/en.json"
 * }
 *
 * // Single language config
 * const singleI18n = {
 *      "sdk.modal.title": "Modal title",
 *      "sdk.modal.description": "Modal description, with {{ estimatedReward }} of gains possible",
 * }
 * ```
 *
 * @category Config
 */
export declare type I18nConfig = Record<Language, LocalizedI18nConfig> | LocalizedI18nConfig;

/**
 * Represent an iframe event
 */
export declare type IFrameEvent = IFrameRpcEvent | IFrameLifecycleEvent | ClientLifecycleEvent;

/**
 * Event related to the iframe lifecycle
 * @ignore
 */
export declare type IFrameLifecycleEvent = {
    iframeLifecycle: "connected" | "show" | "hide";
    data?: never;
} | DoBackupEvent | RemoveBackupEvent | HandshakeRequestEvent;

/**
 * Represent an iframe rpc event
 */
export declare type IFrameRpcEvent = {
    id: string;
    topic: ExtractedParametersFromRpc<IFrameRpcSchema>["method"];
    data: CompressedData;
};

/**
 * RPC interface that's used for the iframe communication
 *
 * Define all the methods available within the iFrame RPC client
 *
 * @group RPC Schema
 *
 * @remarks
 * Here is the list of methods available:
 *
 * ### frak_listenToWalletStatus
 *  - Params: None
 *  - Returns: {@link WalletStatusReturnType}
 *
 * ### frak_displayModal
 * - Params: [{@link ModalRpcStepsInput}, name: string, metadata?: {@link ModalRpcMetadata}]
 * - Returns: {@link ModalRpcStepsResultType}
 *
 * ### frak_sendInteraction
 *  - Params: [productId: Hex, interaction: {@link PreparedInteraction}, signature?: Hex]
 *  - Returns: {@link SendInteractionReturnType}
 *
 * ### frak_sso
 *  - Params [params: {@link OpenSsoParamsType}, name: string, customCss?: string]
 *  - Returns: undefined
 *
 *  ### frak_getProductInformation
 *  - Params: None
 *  - Returns: {@link GetProductInformationReturnType}
 *
 * ### frak_displayEmbeddedWallet
 * - Params: [{@link DisplayEmbeddedWalletParamsType}]
 * - Returns: {@link DisplayEmbeddedWalletResultType}
 */
export declare type IFrameRpcSchema = [
/**
* Method used to listen to the wallet status
*/
    {
    Method: "frak_listenToWalletStatus";
    Parameters?: undefined;
    ReturnType: WalletStatusReturnType;
},
/**
* Method to display a modal with the provided steps
*/
    {
    Method: "frak_displayModal";
    Parameters: [
    requests: ModalRpcStepsInput,
    metadata: ModalRpcMetadata | undefined,
    configMetadata: FrakWalletSdkConfig["metadata"]
    ];
    ReturnType: ModalRpcStepsResultType;
},
/**
* Method to transmit a user interaction
*/
    {
    Method: "frak_sendInteraction";
    Parameters: [
    productId: Hex,
    interaction: PreparedInteraction,
    signature?: Hex
    ];
    ReturnType: SendInteractionReturnType;
},
/**
* Method to start a SSO
*  todo: Should also support direct tracking via a consumeKey
*/
    {
    Method: "frak_sso";
    Parameters: [
    params: OpenSsoParamsType,
    name: string,
    customCss?: string
    ];
    ReturnType: undefined;
},
/**
* Method to get current product information's
*  - Is product minted?
*  - Does it have running campaign?
*  - Estimated reward on actions
*/
    {
    Method: "frak_getProductInformation";
    Parameters?: undefined;
    ReturnType: GetProductInformationReturnType;
},
/**
* Method to show the embedded wallet, with potential customization
*/
    {
    Method: "frak_displayEmbeddedWallet";
    Parameters: [
    request: DisplayEmbeddedWalletParamsType,
    metadata: FrakWalletSdkConfig["metadata"]
    ];
    ReturnType: DisplayEmbeddedWalletResultType;
}
];

/**
 * IFrame transport interface
 */
export declare type IFrameTransport = {
    /**
     * Wait for the connection to be established
     */
    waitForConnection: Promise<boolean>;
    /**
     * Wait for the setup to be done
     */
    waitForSetup: Promise<void>;
    /**
     * Function used to perform a single request via the iframe transport
     */
    request: RequestFn<IFrameRpcSchema>;
    /**
     * Function used to listen to a request response via the iframe transport
     */
    listenerRequest: ListenerRequestFn<IFrameRpcSchema>;
    /**
     * Function used to destroy the iframe transport
     */
    destroy: () => Promise<void>;
};

/**
 * Each interactions types according to the product types
 */
export declare const interactionTypes: {
    readonly press: {
        readonly openArticle: "0xc0a24ffb";
        readonly readArticle: "0xd5bd0fbe";
    };
    readonly dapp: {
        readonly proofVerifiableStorageUpdate: "0x2ab2aeef";
        readonly callableVerifiableStorageUpdate: "0xa07da986";
    };
    readonly webshop: {
        readonly open: "0xb311798f";
    };
    readonly referral: {
        readonly referred: "0x010cc3b9";
        readonly createLink: "0xb2c0f17c";
    };
    readonly purchase: {
        readonly started: "0xd87e90c3";
        readonly completed: "0x8403aeb4";
        readonly unsafeCompleted: "0x4d5b14e0";
    };
    readonly retail: {
        readonly customerMeeting: "0x74489004";
    };
};

/**
 * The final keys for each interaction types (e.g. `openArticle`) -> interaction type
 * @inline
 */
export declare type InteractionTypesKey = {
    [K in keyof typeof interactionTypes]: keyof (typeof interactionTypes)[K];
}[keyof typeof interactionTypes];

/**
 * Represent a key provider used for the hashed and secure compression
 *  @ignore
 */
export declare type KeyProvider<DataType> = (value: DataType) => string[];

/**
 * All the languages available
 * @category Config
 */
export declare type Language = "fr" | "en";

/**
 * Type used for a listening request
 * @inline
 */
declare type ListenerRequestFn<TRpcSchema extends RpcSchema> = <TParameters extends ExtractedParametersFromRpc<TRpcSchema> = ExtractedParametersFromRpc<TRpcSchema>, _ReturnType = ExtractedReturnTypeFromRpc<TRpcSchema, TParameters>>(args: TParameters, callback: (result: _ReturnType) => void) => Promise<void>;

/**
 * Map the currency to the locale
 */
export declare const locales: {
    readonly eur: "fr-FR";
    readonly usd: "en-US";
    readonly gbp: "en-GB";
};

/**
 * The keys for each locales
 * @inline
 */
export declare type LocalesKey = keyof typeof locales;

/**
 * A localized i18n config
 * @category Config
 */
export declare type LocalizedI18nConfig = `${string}.css` | {
    [key: string]: string;
};

/**
 * Some configuration options for the embedded view
 *
 * @group Embedded wallet
 */
export declare type LoggedInEmbeddedView = {
    /**
     * The main action to display on the logged in embedded view
     */
    action?: EmbeddedViewActionSharing | EmbeddedViewActionReferred;
};

/**
 * The view when a user is logged out
 * @group Embedded wallet
 */
export declare type LoggedOutEmbeddedView = {
    /**
     * Metadata option when displaying the embedded view
     */
    metadata?: {
        /**
         * The main CTA for the logged out view
         *  - can include some variable, available ones are:
         *      - {REWARD} -> The maximum reward a user can receive when interacting on your website
         *  - can be formatted in markdown
         *
         * If not set, it will default to a internationalized message
         * @deprecated Use the top level `config.customizations.i18n`, or `metadata.i18n` instead
         */
        text?: string;
        /**
         * The text that will be displayed on the login button
         *
         * If not set, it will default to a internationalized message
         * @deprecated Use the top level `config.customizations.i18n`, or `metadata.i18n` instead
         */
        buttonText?: string;
    };
};

/**
 * The login step for a Modal
 *
 * **Input**: Do we allow SSO or not? Is yes then the SSO metadata
 * **Output**: The logged in wallet address
 *
 * @group Modal Display
 */
export declare type LoginModalStepType = GenericModalStepType<"login", LoginWithSso | LoginWithoutSso, {
    wallet: Address;
}>;

/** @inline */
declare type LoginWithoutSso = {
    allowSso?: false;
    ssoMetadata?: never;
};

/** @inline */
declare type LoginWithSso = {
    allowSso: true;
    ssoMetadata?: SsoMetadata;
};

/**
 * RPC metadata for the modal, used on top level modal configuration
 * @group Modal Display
 * @group RPC Schema
 */
export declare type ModalRpcMetadata = {
    header?: {
        title?: string;
        icon?: string;
    };
    targetInteraction?: FullInteractionTypesKey;
    /**
     * Some i18n override for the displayed modal (i.e. update the displayed text only for this modal)
     */
    i18n?: I18nConfig;
} & ({
    isDismissible: true;
    /**
     * @deprecated Use `config.customizations.i18n` or `metadata.i18n` instead
     */
    dismissActionTxt?: string;
} | {
    isDismissible?: false;
    dismissActionTxt?: never;
});

/**
 * Type for the RPC input of a modal
 * Just the `params` type of each `ModalStepTypes`
 * @typeParam T - The list of modal steps we expect to have in the modal
 * @group Modal Display
 * @group RPC Schema
 */
export declare type ModalRpcStepsInput<T extends ModalStepTypes[] = ModalStepTypes[]> = {
    [K in T[number]["key"]]?: Extract<T[number], {
        key: K;
    }>["params"];
};

/**
 * Type for the result of a modal request
 * Just the `returns` type of each `ModalStepTypes`
 * @typeParam T - The list of modal steps we expect to have in the modal
 * @group Modal Display
 * @group RPC Schema
 */
export declare type ModalRpcStepsResultType<T extends ModalStepTypes[] = ModalStepTypes[]> = {
    [K in T[number]["key"]]: Extract<T[number], {
        key: K;
    }>["returns"];
};

/**
 * Metadata that can be used to customize a modal step
 * @group Modal Display
 * @deprecated Use the top level `config.customizations.i18n`, or `metadata.i18n` instead
 */
export declare type ModalStepMetadata = {
    metadata?: {
        /**
         * Custom title for the step
         * If none provided, it will use an internationalized text
         * @deprecated Use the top level `config.customizations.i18n`, or `metadata.i18n` instead
         */
        title?: string;
        /**
         * Custom description for the step
         * If none provided, it will use an internationalized text
         * @deprecated Use the top level `config.customizations.i18n`, or `metadata.i18n` instead
         */
        description?: string;
        /**
         * Custom text for the primary action of the step
         * If none provided, it will use an internationalized text
         * @deprecated Use the top level `config.customizations.i18n`, or `metadata.i18n` instead
         */
        primaryActionText?: string;
        /**
         * Custom text for the secondary action of the step
         * If none provided, it will use an internationalized text
         * @deprecated Use the top level `config.customizations.i18n`, or `metadata.i18n` instead
         */
        secondaryActionText?: string;
    };
};

/**
 * Generic type of steps we will display in the modal to the end user
 * @group Modal Display
 */
export declare type ModalStepTypes = LoginModalStepType | SiweAuthenticateModalStepType | SendTransactionModalStepType | OpenInteractionSessionModalStepType | FinalModalStepType;

/**
 * The open interaction session step for a Modal
 *
 * **Input**: None
 * **Output**: The interactions session period (start and end timestamp)
 *
 * @group Modal Display
 */
export declare type OpenInteractionSessionModalStepType = GenericModalStepType<"openSession", object, OpenInteractionSessionReturnType>;

/**
 * Return type of the open session modal step
 * @inline
 * @ignore
 */
export declare type OpenInteractionSessionReturnType = {
    startTimestamp: number;
    endTimestamp: number;
};

/**
 * Params to start a SSO
 * @group RPC Schema
 */
export declare type OpenSsoParamsType = {
    /**
     * Redirect URL after the SSO (optional)
     */
    redirectUrl?: string;
    /**
     * If the SSO should directly exit after completion
     * @defaultValue true
     */
    directExit?: boolean;
    /**
     * Language of the SSO page (optional)
     * It will default to the current user language (or "en" if unsupported language)
     */
    lang?: "en" | "fr";
    /**
     * Custom SSO metadata
     */
    metadata: SsoMetadata;
};

/**
 * Parse the current URL into a Frak Context
 * @param args
 * @param args.url - The url to parse
 * @returns The parsed Frak context
 */
declare function parse({ url }: {
    url: string;
}): FrakContext | null | undefined;

/**
 * Represent a prepared user interaction, ready to be sent on-chain via the wallet
 */
export declare type PreparedInteraction = {
    handlerTypeDenominator: Hex;
    interactionData: Hex;
};

/**
 * List of the product types per denominator
 */
export declare const productTypes: {
    dapp: number;
    press: number;
    webshop: number;
    retail: number;
    referral: number;
    purchase: number;
};

/**
 * The keys for each product types
 * @inline
 */
export declare type ProductTypesKey = keyof typeof productTypes;

/**
 * Bitmask for each product types
 */
export declare const productTypesMask: Record<ProductTypesKey, bigint>;

/**
 * Remove Frak context from current url
 * @param url - The url to update
 * @returns The new url without the Frak context
 */
declare function remove(url: string): string;

declare type RemoveBackupEvent = {
    iframeLifecycle: "remove-backup";
};

/**
 * Replace the current url with the given Frak context
 * @param args
 * @param args.url - The url to update
 * @param args.context - The context to update
 */
declare function replaceUrl({ url: baseUrl, context, }: {
    url?: string;
    context: Partial<FrakContext> | null;
}): void;

/**
 * Type used for a one shot request function
 * @inline
 */
declare type RequestFn<TRpcSchema extends RpcSchema> = <TParameters extends ExtractedParametersFromRpc<TRpcSchema> = ExtractedParametersFromRpc<TRpcSchema>, _ReturnType = ExtractedReturnTypeFromRpc<TRpcSchema, TParameters>>(args: TParameters) => Promise<_ReturnType>;

declare type RestoreBackupEvent = {
    clientLifecycle: "restore-backup";
    data: {
        backup: string;
    };
};

/**
 * The different Frak RPC error codes
 */
export declare const RpcErrorCodes: {
    readonly parseError: -32700;
    readonly invalidRequest: -32600;
    readonly methodNotFound: -32601;
    readonly invalidParams: -32602;
    readonly internalError: -32603;
    readonly serverError: -32000;
    readonly clientNotConnected: -32001;
    readonly configError: -32002;
    readonly corruptedResponse: -32003;
    readonly clientAborted: -32004;
    readonly walletNotConnected: -32005;
    readonly serverErrorForInteractionDelegation: -32006;
};

/**
 * Raw response that we will receive after an rpc request
 * @ignore
 */
export declare type RpcResponse<TRpcSchema extends RpcSchema, TMethod extends TRpcSchema[number]["Method"] = TRpcSchema[number]["Method"]> = {
    result: Extract<TRpcSchema[number], {
        Method: TMethod;
    }>["ReturnType"];
    error?: never;
} | {
    result?: never;
    error: {
        code: number;
        message: string;
        data?: unknown;
    };
};

/**
 * Parameters that will be used to send an interaction to the blockchain
 * @inline
 */
export declare type SendInteractionParamsType = {
    /**
     * The product id where this interaction has been made
     * @defaultValue keccak256(toHex(window.location.host))
     */
    productId?: Hex;
    /**
     * The prepared interaction, built from an Interaction Encoder
     */
    interaction: PreparedInteraction;
    /**
     * A pre-computed interaction signature
     * If none provided, the delegated interaction validator of your product will sign it (you can manage it in the business dashboard)
     *
     * @defaultValue undefined
     */
    validation?: Hex;
};

/**
 * Return type of the send interaction rpc request
 * @group RPC Schema
 */
export declare type SendInteractionReturnType = {
    /**
     * The id of the interaction in the interaction pool
     */
    delegationId: string;
};

/**
 * The send transaction step for a Modal
 *
 * **Input**: Either a single tx or an array of tx to be sent
 * **Output**: The hash of the tx(s) hash (in case of multiple tx, still returns a single hash because it's bundled on the wallet level)
 *
 * @group Modal Display
 */
export declare type SendTransactionModalStepType = GenericModalStepType<"sendTransaction", {
    tx: SendTransactionTxType | SendTransactionTxType[];
}, SendTransactionReturnType>;

/**
 * Return type of the send transaction rpc request
 * @inline
 */
export declare type SendTransactionReturnType = {
    hash: Hex;
};

/**
 * Generic format representing a tx to be sent
 */
export declare type SendTransactionTxType = {
    to: Address;
    data?: Hex;
    value?: Hex;
};

/**
 * Directly setup the Frak client with an iframe
 * Return when the FrakClient is ready (setup and communication estbalished with the wallet)
 *
 * @param config - The configuration to use for the Frak Wallet SDK
 * @returns a Promise with the Frak Client
 *
 * @example
 * const frakConfig: FrakWalletSdkConfig = {
 *     metadata: {
 *         name: "My app title",
 *     },
 * }
 * const client = await setupClient({ config: frakConfig });
 */
export declare function setupClient({ config, }: {
    config: FrakWalletSdkConfig;
}): Promise<FrakClient | undefined>;

/**
 * The SIWE authentication step for a Modal
 *
 * **Input**: SIWE message parameters
 * **Output**: SIWE result (message signed and wallet signature)
 *
 * @group Modal Display
 */
export declare type SiweAuthenticateModalStepType = GenericModalStepType<"siweAuthenticate", {
    siwe: SiweAuthenticationParams;
}, SiweAuthenticateReturnType>;

/**
 * Return type of the Siwe transaction rpc request
 * @inline
 */
export declare type SiweAuthenticateReturnType = {
    signature: Hex;
    message: string;
};

/**
 * Parameters used send a SIWE rpc request
 */
export declare type SiweAuthenticationParams = Omit<SiweMessage, "address" | "chainId" | "expirationTime" | "issuedAt" | "notBefore"> & {
    expirationTimeTimestamp?: number;
    notBeforeTimestamp?: number;
};

/**
 * SSO Metadata
 */
export declare type SsoMetadata = {
    /**
     * URL to your client, if provided will be displayed in the SSO header
     */
    logoUrl?: string;
    /**
     * Link to your homepage, if referenced your app name will contain a link on the sso page
     */
    homepageLink?: string;
};

/**
 * The type for the amount of tokens
 */
export declare type TokenAmountType = {
    amount: number;
    eurAmount: number;
    usdAmount: number;
    gbpAmount: number;
};

/**
 * Populate the current url with the given Frak context
 * @param args
 * @param args.url - The url to update
 * @param args.context - The context to update
 * @returns The new url with the Frak context
 */
declare function update({ url, context, }: {
    url?: string;
    context: Partial<FrakContext>;
}): string | null;

/**
 * @ignore
 * @inline
 */
declare type WalletConnected = {
    key: "connected";
    wallet: Address;
    interactionToken?: string;
    interactionSession?: {
        startTimestamp: number;
        endTimestamp: number;
    };
};

/**
 * @ignore
 * @inline
 */
declare type WalletNotConnected = {
    key: "not-connected";
    wallet?: never;
    interactionToken?: never;
    interactionSession?: never;
};

/**
 * RPC Response for the method `frak_listenToWalletStatus`
 * @group RPC Schema
 */
export declare type WalletStatusReturnType = WalletConnected | WalletNotConnected;

export { }
