import { Address, Hex, Hash, Network, Prettify } from '@keyban/types';
export * from '@keyban/types';
export { ApplicationFeature, ApplicationThemeMode, AuthMethod, Currency, DppProductStatus, Network } from '@keyban/types';
import { GqlKeybanClient_TokenContractFragment, GqlKeybanClient_OrderFragment } from './graphql.js';
export { GqlKeybanClient_AssetTransferFragment as KeybanAssetTransfer, GqlKeybanClient_NftFragment as KeybanNft, GqlKeybanClient_NftBalanceFragment as KeybanNftBalance, GqlKeybanClient_TokenBalanceFragment as KeybanTokenBalance } from './graphql.js';
import { IKeybanApi, KeybanApiStatus } from './api.js';
export { ApiClient, ApiServer, AuthSendOtpArgs, AuthSignInArgs, AuthUpdateUserArgs, IAccountService, IApplicationService, IAuthService, IClientShareStorageService, IDppService, IInvestService, ILoyaltyService, ISignerService } from './api.js';
import { ApolloClient } from '@apollo/client/core';
export { CryptoError, CryptoErrorType, IFrameApiError, IFrameApiErrorType, JwtError, JwtErrorType, KeybanBaseError, SdkError, SdkErrorTypes } from './errors.js';
import '@graphql-typed-document-node/core';

/**
 * EIP‑1559 fee parameters for EVM transactions.
 * Used by EVM account transfer methods to override gas pricing when needed.
 * @example
 * const fees: EvmFeeDetails = { maxFeePerGas: 30n * 10n ** 9n, maxPriorityFeePerGas: 2n * 10n ** 9n };
 */
type EvmFeeDetails = {
    /** The maximum fee per unit of gas. */
    maxFeePerGas: bigint;
    /** The maximum priority fee per unit of gas. */
    maxPriorityFeePerGas: bigint;
};

/**
 * Stellar fee per operation represented as a string in stroops.
 * In congestion, Horizon exposes a higher mode fee; otherwise it's the base fee (100 stroops).
 * @example
 * const fee: StellarFeeDetails = "100"; // 100 stroops per operation
 */
type StellarFeeDetails = string;

/**
 * @module Account
 * Public account and transfer primitives used by chain-specific clients.
 */

type FeeDetails = EvmFeeDetails | StellarFeeDetails;
/**
 * Represents a transaction fee estimation returned by estimation methods.
 * The concrete shape of the `details` field depends on the underlying network:
 * - EVM chains: {@link EvmFeeDetails} (EIP-1559 fields)
 * - Stellar: {@link StellarFeeDetails} (fee per operation as string)
 * @see {@link KeybanAccount.estimateTransfer}
 * @see {@link KeybanAccount.estimateERC20Transfer}
 * @see {@link KeybanAccount.estimateNftTransfer}
 */
type FeesEstimation = {
    /**
     * The total maximum fees for the transaction.
     */
    maxFees: bigint;
    /**
     * Parameters to set when constructing a transaction to ensure the estimation maxFees.
     */
    details: FeeDetails;
};
/**
 * Parameters for transferring ERC‑20-like fungible tokens.
 * @template TFeeDetails Network-specific fee type (defaults to {@link FeeDetails}).
 * @property contractAddress The token contract address.
 * @property to The recipient wallet address.
 * @property value Amount to transfer, in the token's smallest unit.
 * @property [fees] Optional network-specific fee parameters.
 * @see {@link KeybanAccount.transferERC20}
 * @see {@link SdkErrorTypes}
 */
type TransferERC20Params<TFeeDetails = FeeDetails> = {
    contractAddress: Address;
    to: Address;
    value: bigint;
    fees?: TFeeDetails;
};
/**
 * Parameters for transferring NFTs (ERC‑721 / ERC‑1155 on EVM chains).
 * @template TFeeDetails Network-specific fee type (defaults to {@link FeeDetails}).
 * @property contractAddress The NFT contract address.
 * @property tokenId The token identifier.
 * @property to The recipient wallet address.
 * @property [value] Amount to transfer for ERC‑1155 (required and > 0), ignored for ERC‑721.
 * @property standard NFT standard to use: "ERC721" | "ERC1155".
 * @property [fees] Optional network-specific fee parameters.
 * @see {@link KeybanAccount.transferNft}
 * @see {@link SdkErrorTypes}
 */
type TransferNftParams<TFeeDetails = FeeDetails> = {
    contractAddress: Address;
    tokenId: bigint;
    to: Address;
    value?: bigint;
    standard: "ERC721" | "ERC1155";
    fees?: TFeeDetails;
};
/**
 * Parameters to estimate an ERC‑20 transfer, without fees.
 * Derived from {@link TransferERC20Params} by omitting `fees`.
 */
type EstimateERC20TransferParams = Omit<TransferERC20Params, "fees">;
/**
 * Parameters to estimate an NFT transfer, without fees.
 * Derived from {@link TransferNftParams} by omitting `fees`.
 */
type EstimateNftTransferParams = Omit<TransferNftParams, "fees">;
/**
 * Abstract account bound to a specific chain implementation (EVM, Starknet, Stellar).
 * Provides methods to sign messages and to transfer/estimate fees for native currency,
 * ERC‑20-like tokens, and NFTs, when supported by the target network.
 * Obtain an instance via {@link KeybanClient.initialize}.
 * @see {@link KeybanClient}
 */
declare abstract class KeybanAccount {
    /**
     * The blockchain address associated with the account.
     */
    abstract address: Address;
    /**
     * The public key associated with the account.
     */
    abstract publicKey: string;
    protected api: IKeybanApi;
    /**
     * Internal constructor used by chain-specific clients.
     * @param api - Keyban API facade for remote operations.
     * @internal
     */
    constructor(api: IKeybanApi);
    /**
     * Sign a message with the account's key material.
     * @param message - The message to sign.
     * @returns Promise resolving to the signature. EVM returns hex, Stellar returns base64 string.
     * @throws {Error} On signing failures.
     * @see {@link KeybanClient}
     * @example
     * import { KeybanClient, Network } from "@keyban/sdk-base";
     *
     * const client = new KeybanClient({ apiUrl: "https://api.prod.keyban.io", appId: "YOUR_APP_ID", network: Network.EthereumAnvil });
     * const account = await client.initialize();
     * const signature = await account.signMessage("Hello Keyban");
     * console.log(signature);
     */
    abstract signMessage(message: string): Promise<Hex | string | string[]>;
    /**
     * Transfer native currency to a recipient.
     * @param to - Recipient address.
     * @param value - Amount to transfer in the smallest unit (e.g., wei, stroop).
     * @param [fees] - Optional network-specific fee parameters.
     * @returns Promise resolving to the transaction hash/string.
     * @throws {SdkError} {@link SdkErrorTypes.AddressInvalid} | {@link SdkErrorTypes.AmountInvalid}
     * @example
     * import { KeybanClient, Network, type Address } from "@keyban/sdk-base";
     *
     * const client = new KeybanClient({
     *   apiUrl: "https://api.prod.keyban.io",
     *   appId: "YOUR_APP_ID",
     *   network: Network.EthereumAnvil,
     * });
     * const account = await client.initialize();
     *
     * const recipient: Address = "0x0000000000000000000000000000000000000001";
     * const value = 1_000_000_000_000_000_000n; // 1 ETH in wei
     * const txHash = await account.transfer(recipient, value);
     * console.log(txHash);
     */
    abstract transfer(to: Address, value: bigint, fees?: FeeDetails): Promise<Hash | string>;
    /**
     * Estimate maximum fees to transfer native currency.
     * @param to - Recipient address.
     * @returns Promise resolving to {@link FeesEstimation}.
     * @throws {Error} On estimation failure.
     * @example
     * import { KeybanClient, Network, type Address } from "@keyban/sdk-base";
     * const client = new KeybanClient({ apiUrl: "https://api.prod.keyban.io", appId: "YOUR_APP_ID", network: Network.EthereumAnvil });
     * const account = await client.initialize();
     * const recipient: Address = "0x0000000000000000000000000000000000000001";
     * const estimation = await account.estimateTransfer(recipient);
     * console.log(estimation.maxFees.toString());
     */
    abstract estimateTransfer(to: Address): Promise<FeesEstimation>;
    /**
     * Transfer ERC‑20-like fungible tokens.
     * @param params - Transfer parameters.
     * @returns Promise resolving to the transaction hash/string.
     * @throws {SdkError} {@link SdkErrorTypes.AddressInvalid} | {@link SdkErrorTypes.AmountInvalid} | {@link SdkErrorTypes.RecipientAddressEqualsSender}
     * @example
     * import { KeybanClient, Network, type Address } from "@keyban/sdk-base";
     *
     * const client = new KeybanClient({ apiUrl: "https://api.prod.keyban.io", appId: "YOUR_APP_ID", network: Network.EthereumAnvil });
     *
     * const txHash = await account.transferERC20({
     *   contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as Address, // USDC
     *   to: "0x0000000000000000000000000000000000000001" as Address,
     *   value: 1_000_000n, // 1 USDC (6 decimals)
     * });
     * console.log(txHash);
     */
    abstract transferERC20(params: TransferERC20Params): Promise<Hash | string>;
    /**
     * Estimate maximum fees for an ERC‑20 token transfer.
     * @param params - Transfer parameters without explicit fees.
     * @returns Promise resolving to {@link FeesEstimation}.
     * @throws {Error} On estimation failure.
     * @example
     * import { KeybanClient, Network, type Address } from "@keyban/sdk-base";
     * const client = new KeybanClient({ apiUrl: "https://api.prod.keyban.io", appId: "YOUR_APP_ID", network: Network.EthereumAnvil });
     * const account = await client.initialize();
     * const estimation = await account.estimateERC20Transfer({
     *   contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as Address,
     *   to: "0x0000000000000000000000000000000000000001" as Address,
     *   value: 1_000_000n,
     * });
     * console.log(estimation.details);
     */
    abstract estimateERC20Transfer(params: EstimateERC20TransferParams): Promise<FeesEstimation>;
    /**
     * Transfer an NFT (ERC‑721 / ERC‑1155).
     * @param params - NFT transfer parameters.
     * @returns Promise resolving to the transaction hash.
     * @throws {SdkError} {@link SdkErrorTypes.AddressInvalid} | {@link SdkErrorTypes.RecipientAddressEqualsSender} | {@link SdkErrorTypes.AmountRequired} | {@link SdkErrorTypes.AmountInvalid} | {@link SdkErrorTypes.AmountIrrelevant} | {@link SdkErrorTypes.InvalidNftStandard}
     * @example
     * import { KeybanClient, Network, type Address } from "@keyban/sdk-base";
     *
     * const client = new KeybanClient({ apiUrl: "https://api.prod.keyban.io", appId: "YOUR_APP_ID", network: Network.EthereumAnvil });
     * const account = await client.initialize();
     *
     * // ERC-721
     * await account.transferNft({
     *   contractAddress: "0xABC..." as Address,
     *   tokenId: 123n,
     *   to: "0x0000000000000000000000000000000000000001" as Address,
     *   standard: "ERC721",
     * });
     *
     * // ERC-1155
     * await account.transferNft({
     *   contractAddress: "0xDEF..." as Address,
     *   tokenId: 456n,
     *   to: "0x0000000000000000000000000000000000000001" as Address,
     *   value: 5n,
     *   standard: "ERC1155",
     * });
     */
    abstract transferNft(params: TransferNftParams): Promise<Hash>;
    /**
     * Estimate maximum fees for an NFT transfer (ERC‑721 / ERC‑1155).
     * @param params - NFT estimation parameters (without explicit fees).
     * @returns Promise resolving to {@link FeesEstimation}.
     * @throws {Error} On estimation failure or invalid parameters.
     * @example
     * import { KeybanClient, Network, type Address } from "@keyban/sdk-base";
     * const client = new KeybanClient({ apiUrl: "https://api.prod.keyban.io", appId: "YOUR_APP_ID", network: Network.EthereumAnvil });
     * const account = await client.initialize();
     * const estimation = await account.estimateNftTransfer({
     *   contractAddress: "0xDEF..." as Address,
     *   tokenId: 456n,
     *   to: "0x0000000000000000000000000000000000000001" as Address,
     *   value: 5n,
     *   standard: "ERC1155",
     * });
     * console.log(estimation.maxFees);
     */
    abstract estimateNftTransfer(params: EstimateNftTransferParams): Promise<FeesEstimation>;
}

/**
 * Represents a storage provider for the client share.
 *
 * The purpose of `ClientShareProvider` is to provide an interface that allows integrators
 * to save and restore the client share of their customers. The integrator has the
 * responsibility to securely store the client share.
 * @remarks
 * The client share is not considered sensitive data because only the client
 * can use it, and its usage is secured by strong authentication between the client
 * and the Keyban services.
 *
 * ### Example Implementation
 *
 * Below is a basic implementation of a `CustomClientShareProvider` using a fetch-based provider:
 *
 * ```typescript
 * class CustomClientShareProvider implements ClientShareProvider {
 *    // Retrieves the client share data.
 *    // @returns - A promise resolving to the client share string or `null` if unavailable.
 *   async get(): Promise<string | null> {
 *     try {
 *       const response = await fetch("/api/clientShare", {
 *         method: "GET",
 *         headers: { "Content-Type": "application/json" },
 *       });
 *
 *       if (!response.ok) {
 *         console.error("Failed to fetch client share:", response.statusText);
 *         return null;
 *       }
 *
 *       return response.text();
 *     } catch (error) {
 *       console.error("Error retrieving client share:", error);
 *       return null;
 *     }
 *   }
 *
 *
 *   // Saves the client share data.
 *   // @param clientShare - The client share string to store.
 *   // @returns - A promise that resolves when the operation is complete.
 *   async set(clientShare: string): Promise<void> {
 *     try {
 *       const response = await fetch("/api/clientShare", {
 *         method: "POST",
 *         headers: { "Content-Type": "application/json" },
 *         body: JSON.stringify({ clientShare }),
 *       });
 *
 *       if (!response.ok) {
 *         throw new Error(`Failed to save client share: ${response.statusText}`);
 *       }
 *     } catch (error) {
 *       console.error("Error saving client share:", error);
 *       throw error;
 *     }
 *   }
 * }
 * ```
 *
 * This implementation assumes the existence of an API endpoint `/api/clientShare`
 * to manage the client share on the server side. The integrator should ensure that
 * the endpoint is appropriately secured.
 */
interface ClientShareProvider {
    /**
     * Retrieves the client share information.
     * @param key - The key associated with the client share.
     * @returns - A promise that resolves to a string containing the client share, or null if not available.
     */
    get(key: string): Promise<string | null>;
    /**
     * Sets the client share information.
     * @param key - The key associated with the client share.
     * @param clientShare - The client share string to set.
     * @returns - A promise that resolves when the client share has been set.
     */
    set(key: string, clientShare: string): Promise<unknown>;
}

/**
 * @module Chains
 */
/**
 * Represents the unit of fees in a specific blockchain.
 * @property {string} symbol - The symbol of the fee unit (e.g., "gwei").
 * @property {number} decimals - The number of decimal places for the fee unit.
 */
type FeesUnit = {
    symbol: string;
    decimals: number;
};
/**
 * Represents the native currency of a blockchain network.
 * @property {string} name - The name of the native currency (e.g., "Ether").
 * @property {string} symbol - The symbol of the native currency (e.g., "ETH").
 * @property {number} decimals - The number of decimal places the currency can be divided into.
 * @example
 * const nativeCurrency = {
 *   name: "Ether",
 *   symbol: "ETH",
 *   decimals: 18
 * };
 * @example
 * const nativeCurrency = {
 *   name: "Bitcoin",
 *   symbol: "BTC",
 *   decimals: 8
 * };
 */
type NativeCurrency = {
    name: string;
    symbol: string;
    decimals: number;
};

/**
 * @module Client
 */

/**
 * Configuration options for initializing the Keyban client.
 */
type KeybanClientConfig = {
    /**
     * The base URL of the API. Optional. Defaults to "https://api.prod.keyban.io" if not provided.
     */
    apiUrl?: URL | string;
    /**
     * The application ID.
     */
    appId: string;
    /**
     * The blockchain configuration for Keyban.
     */
    network: Network;
    /**
     * The client share provider.
     */
    clientShareProvider?: ClientShareProvider;
    /**
     * An optional API implementation to use instead of the default iframe-based one.
     * Pass this to use the SDK in non-browser environments (e.g., Node.js).
     */
    api?: IKeybanApi;
};
type MetadataConfig = {
    network: {
        rpcUrl: string;
        indexerUrl: string;
        horizonUrl?: string;
    };
};
declare abstract class KeybanClientBase {
    #private;
    /**
     * The Keyban API URL, defaulting to "https://api.prod.keyban.io".
     */
    apiUrl: URL;
    /**
     * The application ID used for authentication with the Keyban API.
     */
    appId: string;
    /**
     * The blockchain used by Keyban.
     */
    network: Network;
    /**
     * The Apollo GraphQL client used for making API requests.
     */
    apolloClient: ApolloClient;
    protected clientShareProvider: ClientShareProvider;
    protected metadataConfig: Promise<MetadataConfig>;
    constructor(config: KeybanClientConfig, metadataConfig?: Promise<MetadataConfig>);
    get api(): IKeybanApi;
    /**
     * Retrieves the native currency details associated with the current network.
     *
     * Returns an object that includes the native currency's name, symbol, and decimal precision
     * for the active {@link KeybanClientBase.network}.
     * @returns The native currency information for the current network.
     */
    get nativeCurrency(): NativeCurrency;
    /**
     * Retrieves the fee unit configuration based on the current network.
     *
     * Maps supported networks to their fee unit details, including symbol and number of decimals.
     * Supported configurations include:
     * - EthereumAnvil & PolygonAmoy: symbol "gwei", decimals 9
     * - StarknetDevnet, StarknetSepolia & StarknetMainnet: symbol "FRI", decimals 18
     * - StellarQuickstart, StellarTestnet & StellarMainnet: symbol "stroop", decimals 7
     * @returns The fee unit configuration for the active network.
     */
    get feesUnit(): FeesUnit;
    /**
     * Performs a health check on the Keyban API to determine its operational status.
     * @returns - A promise resolving to the API status, either `"operational"` or `"down"`.
     * @example
     * ```typescript
     * const status = await client.apiStatus();
     * console.log(`API Status: ${status}`);
     * ```
     * @throws {Error} Throws an error if the health check request fails.
     * @see {@link KeybanApiStatus}
     */
    apiStatus(): Promise<KeybanApiStatus>;
    /**
     * Initializes a `KeybanAccount` associated with the current client.
     * This method sets up the account by retrieving or generating the client share,
     * and prepares the account for transactions and other operations.
     * @returns - A promise that resolves to an instance of `KeybanAccount`.
     * @throws {SdkError} If initialization fails due to signing errors.
     * @example
     * ```typescript
     * const account = await client.initialize();
     * console.log(`Account address: ${account.address}`);
     * ```
     * @see {@link KeybanAccount}
     */
    abstract initialize(): Promise<KeybanAccount>;
}
/**
 * Main client for interacting with the Keyban API and associated services.
 * This class provides methods to initialize accounts, retrieve balances, query NFTs,
 * and interact with the Keyban blockchain.
 * @remarks
 * The `KeybanClient` serves as the primary interface for developers to interact with
 * the Keyban ecosystem. It handles authentication, communication with the Keyban API,
 * and provides utility methods for common tasks.
 * @example
 * ```typescript
 * // Initialize the client
 * const client = new KeybanClient({
 *   apiUrl: "https://api.prod.keyban.io",
 *   appId: "your-app-id",
 *   network: Network.EthereumAnvil,
 * });
 *
 * // Initialize an account
 * const account = await client.initialize();
 * ```
 * @see {@link KeybanAccount}
 */
declare class KeybanClient extends KeybanClientBase {
    #private;
    /**
     * Creates a new instance of `KeybanClient`.
     * @param config - The configuration object to initialize the client.
     * @throws {SdkError} If the configuration is invalid.
     * @example
     * ```typescript
     * const client = new KeybanClient({
     *   apiUrl: "https://api.prod.keyban.io",
     *   appId: "your-app-id",
     *   network: Network.EthereumAnvil,
     * });
     * ```
     */
    constructor(config: KeybanClientConfig);
    initialize(): Promise<KeybanAccount>;
}

/**
 * Represents a balance with optional metadata.
 * @example
 * const balance: Balance = { raw: 1_000_000_000_000_000_000n, decimals: 18, symbol: "ETH", isNative: true };
 * const tokenBalance: Balance = { raw: 500_000_000_000_000_000n, decimals: 18, symbol: "DAI" };
 */
type Balance = {
    /**  The raw balance value. */
    raw: string | bigint;
    /** The number of decimal places for the balance. */
    decimals?: number;
    /** The symbol of the currency. */
    symbol?: string;
    /** Indicates if the balance is in the native currency. */
    isNative?: boolean;
    /** Indicates if the balance is used for fees. */
    isFees?: boolean;
};
/**
 * Format a balance using the client's native/fee units or the token metadata.
 * @param client - The Keyban client providing network native currency and fee units.
 * @param balance - Raw amount and optional hints: decimals/symbol/isNative/isFees.
 * @param [token] - Optional token metadata used when `isNative`/`isFees` are false.
 * @returns A formatted string with decimals applied and symbol when available.
 * @example
 * import { KeybanClient, Network, formatBalance } from "@keyban/sdk-base";
 * const client = new KeybanClient({ apiUrl: "https://api.prod.keyban.io", appId: "APP", network: Network.EthereumAnvil });
 * const native = { raw: 1_000_000_000_000_000_000n, isNative: true };
 * console.log(formatBalance(client, native)); // "1 ETH"
 * const token = { id: "1", type: "ERC20", name: "Tether", symbol: "USDT", decimals: 6 } as KeybanToken;
 * console.log(formatBalance(client, { raw: 1_000_000n }, token)); // "1 USDT"
 * console.log(formatBalance(client, { raw: 1_000n, isFees: true })); // e.g. "0.000001 gwei"
 */
declare function formatBalance(client: KeybanClient, balance: Balance, token?: GqlKeybanClient_TokenContractFragment): string;

type OrderItem = {
    id: number;
    itemId: number;
    name: string;
    price: number;
};
type Order = Prettify<Omit<GqlKeybanClient_OrderFragment, "items"> & {
    items: OrderItem[];
}>;
/**
 * Arguments for paginating a collection.
 * @property {number} first - The maximum number of items to retrieve in the current page.
 */
type PaginationArgs = {
    /** The maximum number of items to retrieve in the current page. */
    first?: number;
    /** A cursor representing the starting point for the next page */
    after?: string;
};
/**
 * Represents the types of authentication connections available.
 * @type {("username-password" | "google-oauth2")}
 * @property {"username-password"} username-password - Standard username and password authentication.
 * @property {"email"} email - One time password send through email.
 * @property {"sms"} sms - One time password send through sms.
 * @property {"google-oauth2"} google-oauth2 - Google OAuth 2.0 authentication.
 */
type AuthConnection = "username-password" | "email" | "sms" | "google-oauth2";

export { type AuthConnection, type Balance, type ClientShareProvider, type EstimateERC20TransferParams, type EstimateNftTransferParams, type EvmFeeDetails, type FeeDetails, type FeesEstimation, type FeesUnit, IKeybanApi, KeybanAccount, KeybanApiStatus, KeybanClient, type KeybanClientConfig, GqlKeybanClient_OrderFragment as KeybanOrder, GqlKeybanClient_TokenContractFragment as KeybanToken, type NativeCurrency, type Order, type OrderItem, type PaginationArgs, type StellarFeeDetails, type TransferERC20Params, type TransferNftParams, formatBalance };
