import { RequireExactlyOne } from 'type-fest';
import { TypedData, TypedDataToPrimitiveTypes, TypedDataDomain } from 'abitype';

declare enum DappErrorName {
    DecodeError = "Decode Error",
    InvalidParams = "Invalid Params",
    UserRejected = "User Rejected",
    NotAllowed = "Not Allowed"
}
declare class DappError extends Error {
    rawError?: unknown;
    constructor(message: string, name?: string, rawError?: unknown);
}

declare function parseSearchWith(parser: (str: string) => any): (searchStr: string) => any;
declare function stringifySearchWith(stringify: (search: any) => string, parser?: (str: string) => any): (search: Record<string, any>) => string;
declare const decodeSearch: (searchStr: string) => any;
declare const encodeSearch: (search: Record<string, any>) => string;

declare const safeExec: <T>(fn: () => T) => T | null;

/**
 * Convert from a Base64URL-encoded string to an Array Buffer. Best used when converting a
 * credential ID from a JSON string to an ArrayBuffer, like in allowCredentials or
 * excludeCredentials
 *
 * Helper method to compliment `bufferToBase64URLString`
 */
declare function base64URLStringToBuffer(base64URLString: string): ArrayBuffer;
/**
 * Convert the given array buffer into a Base64URL-encoded string. Ideal for converting various
 * credential response ArrayBuffers to string for sending back to the server as JSON.
 *
 * Helper method to compliment `base64URLStringToBuffer`
 */
declare function bufferToBase64URLString(buffer: ArrayBuffer): string;
declare function hexToArrayBuffer(input: string): ArrayBuffer;
declare function bufferToHex(buffer: ArrayBuffer): string;
declare function appendBuffer(buffer1: ArrayBuffer, buffer2: ArrayBuffer): ArrayBuffer;
declare function bufferToUTF8String(value: ArrayBuffer): string;
declare function utf8StringToBuffer(value: string): ArrayBuffer;
declare function hexToUTF8String(value: string): string;
declare function remove0x(hex: string): string;
declare function append0x(hex: string): string;
declare function hexToString(hex: string): string;
declare function base64urlToHex(s: string): string;

declare function isStandaloneBrowser(): boolean;

type Hash = string;
type HexNumber = string;
type HexString = string;
type PackedSince = string;
interface Header {
    timestamp: HexNumber;
    number: HexNumber;
    epoch: HexNumber;
    compactTarget: HexNumber;
    dao: Hash;
    hash: Hash;
    nonce: HexNumber;
    parentHash: Hash;
    proposalsHash: Hash;
    transactionsRoot: Hash;
    extraHash: Hash;
    version: HexNumber;
}
declare type HashType = 'type' | 'data' | 'data1';
interface Script {
    codeHash: Hash;
    hashType: HashType;
    args: HexString;
}
interface OutPoint {
    txHash: Hash;
    index: HexNumber;
}
declare type DepType = 'depGroup' | 'code';
interface CellDep {
    outPoint: OutPoint;
    depType: DepType;
}
interface Input {
    previousOutput: OutPoint;
    since: PackedSince;
}
interface Output {
    capacity: HexString;
    lock: Script;
    type?: Script;
}
interface WitnessArgs {
    lock?: HexString;
    inputType?: HexString;
    outputType?: HexString;
}
interface RawTransaction {
    cellDeps: CellDep[];
    hash?: Hash;
    headerDeps: Hash[];
    inputs: Input[];
    outputs: Output[];
    outputsData: HexString[];
    version: HexString;
}
interface CKBTransaction {
    cellDeps: CellDep[];
    hash?: Hash;
    headerDeps: Hash[];
    inputs: Input[];
    outputs: Output[];
    outputsData: HexString[];
    version: HexNumber;
    witnesses: HexString[];
}
interface CkbTransactionRequest {
    from: string;
    to: string;
    amount: string;
}
interface CkbDappConfig extends JoyIDConfig {
    name?: string;
    logo?: string;
    redirectURL?: string;
    rpcURL?: string;
    network?: 'mainnet' | 'testnet';
}
interface SignCkbTxRequest extends CkbDappConfig {
    tx: CkbTransactionRequest;
    signerAddress: string;
    redirectURL: string;
}
interface SignCkbRawTxRequest extends CkbDappConfig {
    tx: CKBTransaction;
    signerAddress: string;
    redirectURL: string;
    witnessIndexes?: number[];
}
interface CotaNFTTransactionRequest {
    from: string;
    to: string;
    tokenKey?: string;
    tokenId?: string;
    tokenIndex?: string;
}
interface SignCotaNFTRequest extends CkbDappConfig {
    tx: CotaNFTTransactionRequest;
    signerAddress: string;
    redirectURL: string;
}

declare enum SigningAlg {
    RS256 = -257,
    ES256 = -7
}
interface JoyIDConfig {
    joyidAppURL?: string;
    joyidServerURL?: string;
}
interface DappConfig extends JoyIDConfig {
    name?: string;
    logo?: string;
    state?: unknown;
}
type SessionKeyType = 'main_session_key' | 'sub_session_key';
type WebauthnKeyType = 'main_key' | 'sub_key';
type CredentialKeyType = SessionKeyType | WebauthnKeyType;
type Base64URLString = string;
type RequestNetwork = 'nervos' | 'nostr' | 'ethereum' | 'btc-p2tr' | 'btc-p2wpkh' | 'btc-auto';
interface BaseRequest {
    redirectURL: string;
    joyidAppURL?: string;
}
type Hex$1 = `0x${string}`;
interface AuthRequest extends BaseRequest {
    requestNetwork?: RequestNetwork;
    name?: string;
    logo?: string;
    challenge?: string;
    state?: unknown;
}
interface MiniAppBaseRequest {
    name: string;
    logo: string;
    miniAppToken: string;
    callbackUrl: string;
    joyidAppURL?: string;
}
interface MiniAppAuthRequest extends MiniAppBaseRequest {
    requestNetwork?: RequestNetwork;
    challenge?: string;
}
declare enum DappRequestType {
    Auth = "Auth",
    SignMessage = "SignMessage",
    SignEvm = "SignEvm",
    SignPsbt = "SignPsbt",
    BatchSignPsbt = "BatchSignPsbt",
    SignCkbTx = "SignCkbTx",
    SignCotaNFT = "SignCotaNFT",
    SignCkbRawTx = "SignCkbRawTx",
    SignNostrEvent = "SignNostrEvent",
    EncryptNostrMessage = "EncryptNostrMessage",
    EvmWeb2Login = "EvmWeb2Login",
    DecryptNostrMessage = "DecryptNostrMessage",
    AuthMiniApp = "AuthMiniApp",
    SignMiniAppMessage = "SignMiniAppMessage",
    SignMiniAppEvm = "SignMiniAppEvm"
}
declare enum DappCommunicationType {
    Popup = "popup",
    Redirect = "redirect"
}
interface SignMessageResponseData {
    signature: string;
    /**
     * The message that was signed by the authenticator,
     * Note that the message is not the original raw message,
     * but is combined with client data and authenticator data
     * according to [WebAuthn Spec](https://www.w3.org/TR/webauthn-2/#sctn-op-get-assertion).
     */
    message: string;
    /**
     * The public key used to sign the message
     */
    pubkey: string;
    /**
     * The message that was requested to be signed
     */
    challenge: string;
    attestation?: string;
    keyType: CredentialKeyType;
    alg: SigningAlg;
    state?: any;
    requestNetwork?: RequestNetwork;
}
interface AuthResponseData extends Partial<SignMessageResponseData> {
    address: string;
    ethAddress: string;
    nostrPubkey: string;
    pubkey: string;
    challenge?: string;
    message?: string;
    keyType: CredentialKeyType;
    alg: SigningAlg;
    btcAddressType?: 'p2tr' | 'p2wpkh';
    taproot: {
        address: string;
        pubkey: string;
    };
    nativeSegwit: {
        address: string;
        pubkey: string;
    };
}
interface DappResponse<T> {
    error: string;
    data: T;
    state?: any;
}
type AuthResponse = {
    type: DappRequestType.Auth;
} & RequireExactlyOne<DappResponse<AuthResponseData>, 'data' | 'error'>;
type SignMessageResponse = {
    type: DappRequestType.SignMessage;
} & RequireExactlyOne<DappResponse<SignMessageResponseData>, 'data' | 'error'>;
interface BaseSignMessageRequest extends AuthRequest {
    challenge: string;
    isData?: boolean;
    address?: string;
    requestNetwork?: RequestNetwork;
}
interface MiniAppSignMessageRequest extends MiniAppBaseRequest {
    requestNetwork?: RequestNetwork;
    challenge?: string;
    isData?: boolean;
    address: string;
}
interface SignEvmTxResponseData {
    tx: Hex$1;
    state?: any;
}
type SignEvmResponse = {
    type: DappRequestType.SignEvm;
} & RequireExactlyOne<DappResponse<SignEvmTxResponseData>, 'data' | 'error'>;
type SignMessageRequest = RequireExactlyOne<BaseSignMessageRequest, 'address'>;
type BtcSignMessageType = 'bip322-simple' | 'ecdsa';
interface BtcSignMessageRequest extends SignMessageRequest {
    signMessageType: BtcSignMessageType;
}
interface SignCkbTxResponseData {
    tx: CKBTransaction;
    state?: any;
}
type SignCkbTxResponse = {
    type: DappRequestType.SignCkbTx;
} & RequireExactlyOne<DappResponse<SignCkbTxResponseData>, 'data' | 'error'>;
type SignCotaNFTResponseData = SignCkbTxResponseData;
type SignCotaNFTResponse = {
    type: DappRequestType.SignCotaNFT;
} & RequireExactlyOne<DappResponse<SignCotaNFTResponseData>, 'data' | 'error'>;
type SignCkbRawTxResponseData = SignCkbTxResponseData;
type SignCkbRawTxResponse = {
    type: DappRequestType.SignCkbRawTx;
} & RequireExactlyOne<DappResponse<SignCkbRawTxResponseData>, 'data' | 'error'>;
declare const SESSION_KEY_VER = "00";

type Hex = `0x${string}`;
type EthAddress = `0x${string}`;
type AccessList = Array<{
    address: EthAddress;
    storageKeys: Hex[];
}>;
interface TransactionRequest {
    maxPriorityFeePerGas?: string;
    maxFeePerGas?: string;
    to?: string;
    from?: string;
    nonce?: number;
    gasLimit?: string;
    gasPrice?: string;
    data?: string;
    value?: string;
    chainId?: number;
    accessList?: AccessList;
    customData?: Record<string, any>;
    ccipReadEnabled?: boolean;
}
interface EvmChainParameter {
    chainId: number;
    /** The chain name. */
    name: string;
    /** Native currency for the chain. */
    nativeCurrency: {
        name: string;
        symbol: string;
        decimals: number;
    };
    rpcUrls: readonly string[];
    blockExplorerUrls?: string[];
    iconUrls?: string[];
}
type Network = {
    name: string;
    chainId: number;
} | EvmChainParameter;
interface EthNetworkConfig {
    network?: Network;
    rpcURL?: string;
}
type EvmConfig = EthNetworkConfig & DappConfig;
type SignEvmTxRequest = EvmConfig & {
    tx: TransactionRequest;
    isSend?: boolean;
    signerAddress: string;
    redirectURL: string;
    commuType?: DappCommunicationType;
};
type SignTypedDataRequest = EvmConfig & {
    signerAddress: string;
    redirectURL: string;
    commuType?: DappCommunicationType;
    typedData: TypedDataDefinition;
};
type EvmWeb2LoginConfig = EvmConfig & {
    backgroundImage?: string;
};
type EvmWeb2LoginRequest = EvmWeb2LoginConfig & {
    signerAddress?: string;
    redirectURL: string;
    commuType?: DappCommunicationType;
};
interface EvmWeb2LoginResponse {
    uid: string;
    entropy: string;
}
type MiniAppSignEvmTxRequest = EvmConfig & MiniAppBaseRequest & {
    tx: TransactionRequest;
    signerAddress: string;
    isSend?: boolean;
};
type MiniAppSignTypedDataRequest = EvmConfig & MiniAppBaseRequest & {
    signerAddress: string;
    typedData: TypedData;
    isSend?: boolean;
};
type AASignTypedDataParams = Omit<TypedDataDefinition, 'privateKey'>;
/**
 * @description Combines members of an intersection into a readable type.
 *
 * @see {@link https://twitter.com/mattpocockuk/status/1622730173446557697?s=20&t=NdpAcmEFXY01xkqU3KO0Mg}
 * @example
 * Prettify<{ a: string } & { b: string } & { c: number, d: bigint }>
 * => { a: string, b: string, c: number, d: bigint }
 */
type Prettify<T> = {
    [K in keyof T]: T[K];
} & {};
type TypedDataDefinition<typedData extends TypedData | Record<string, unknown> = TypedData, primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, primaryTypes = typedData extends TypedData ? keyof typedData : string> = primaryType extends 'EIP712Domain' ? EIP712DomainDefinition<typedData, primaryType> : MessageDefinition<typedData, primaryType, primaryTypes>;
type MessageDefinition<typedData extends TypedData | Record<string, unknown> = TypedData, primaryType extends keyof typedData = keyof typedData, primaryTypes = typedData extends TypedData ? keyof typedData : string, schema extends Record<string, unknown> = typedData extends TypedData ? TypedDataToPrimitiveTypes<typedData> : Record<string, unknown>, message = schema[primaryType extends keyof schema ? primaryType : keyof schema]> = {
    types: typedData;
} & {
    primaryType: primaryTypes | (primaryType extends primaryTypes ? primaryType : never);
    domain?: (schema extends {
        EIP712Domain: infer domain;
    } ? domain : Prettify<TypedDataDomain>) | undefined;
    message: Record<string, any> extends message ? Record<string, unknown> : message;
};
type EIP712DomainDefinition<typedData extends TypedData | Record<string, unknown> = TypedData, primaryType extends 'EIP712Domain' = 'EIP712Domain', schema extends Record<string, unknown> = typedData extends TypedData ? TypedDataToPrimitiveTypes<typedData> : Record<string, unknown>> = {
    types?: typedData | undefined;
} & {
    primaryType: 'EIP712Domain' | primaryType;
    domain: schema extends {
        EIP712Domain: infer domain;
    } ? domain : Prettify<TypedDataDomain>;
    message?: never | undefined;
};
/**
 * A signer that can sign messages and typed data.
 *
 * @template Inner - the generic type of the inner client that the signer wraps to provide functionality such as signing, etc.
 *
 * @var signerType - the type of the signer (e.g. local, hardware, etc.)
 * @var inner - the inner client of @type {Inner}
 *
 * @method getAddress - get the address of the signer
 * @method signMessage - sign a message
 * @method signTypedData - sign typed data
 */
interface SmartAccountSigner<Inner = any> {
    signerType: string;
    inner: Inner;
    getAddress: () => Promise<Hex>;
    signMessage: (msg: Uint8Array | Hex | string) => Promise<Hex>;
    signTypedData: (params: AASignTypedDataParams) => Promise<Hex>;
}

interface toSignInput {
    /**
     * which input to sign
     */
    index: number;
    /**
     * (at least specify either an address or a publicKey) Which corresponding private key to use for signing
     */
    address: string;
    /**
     * (at least specify either an address or a publicKey) Which corresponding private key to use for signing
     */
    publicKey: string;
    /**
     *  (optionals) sighashTypes
     */
    sighashTypes?: number[];
    /**
     * (optionals) When signing and unlocking Taproot addresses, the tweakSigner is used by default for signature generation. Enabling this allows for signing with the original private key.
     */
    disableTweakSigner?: boolean;
}
interface SignPsbtOptions {
    /**
     * whether finalize psbt after signing, default is true
     */
    autoFinalized: boolean;
    toSignInputs: toSignInput[];
}
interface BtcConfig extends DappConfig {
    requestAddressType?: 'p2tr' | 'p2wpkh' | 'auto';
}
interface SignPsbtRequest extends DappConfig {
    options?: SignPsbtOptions;
    signerAddress: string;
    tx: string;
    redirectURL: string;
    commuType?: DappCommunicationType;
    isSend?: boolean;
}
interface BatchSignPsbtRequest extends DappConfig {
    options?: SignPsbtOptions[];
    signerAddress: string;
    psbts: string[];
    redirectURL: string;
    commuType?: DappCommunicationType;
    isSend?: boolean;
}

/** @deprecated Use numbers instead. */
declare enum EventKind {
    Metadata = 0,
    Text = 1,
    RecommendRelay = 2,
    Contacts = 3,
    EncryptedDirectMessage = 4,
    EventDeletion = 5,
    Repost = 6,
    Reaction = 7,
    BadgeAward = 8,
    ChannelCreation = 40,
    ChannelMetadata = 41,
    ChannelMessage = 42,
    ChannelHideMessage = 43,
    ChannelMuteUser = 44,
    Blank = 255,
    Report = 1984,
    ZapRequest = 9734,
    Zap = 9735,
    RelayList = 10002,
    ClientAuth = 22242,
    HttpAuth = 27235,
    ProfileBadge = 30008,
    BadgeDefinition = 30009,
    Article = 30023
}
interface EventTemplate<K extends number = number> {
    kind: K;
    tags: string[][];
    content: string;
    created_at: number;
}
type UnsignedEvent<K extends number = number> = EventTemplate<K> & {
    pubkey: string;
};
type Event<K extends number = number> = UnsignedEvent<K> & {
    id: string;
    sig: string;
};
interface GetPublicKeyRequest extends JoyIDConfig {
    redirectURL: string;
    name?: string;
    logo?: string;
}
interface SignNostrEventRequest extends GetPublicKeyRequest {
    event: UnsignedEvent<number>;
}
interface SignNostrEventData {
    event: Event<number>;
}
type SignNostrEventResponse = {
    type: DappRequestType.SignNostrEvent;
} & RequireExactlyOne<DappResponse<SignNostrEventData>, 'data' | 'error'>;

interface PopupConfigOptions<T extends DappRequestType = DappRequestType.Auth> {
    /**
     * The number of seconds to wait for a popup response before
     * throwing a timeout error. Defaults to 300s
     */
    timeoutInSeconds?: number;
    /**
     * Accepts an already-created popup window to use. If not specified, the SDK
     * will create its own. This may be useful for platforms like iOS that have
     * security restrictions around when popups can be invoked (e.g. from a user click event)
     */
    popup?: any;
    type: T;
}
declare const openPopup: (url?: string) => Window | null;
interface PopupRerurnType {
    [DappRequestType.Auth]: AuthResponseData;
    [DappRequestType.SignMessage]: SignMessageResponseData;
    [DappRequestType.SignEvm]: SignEvmTxResponseData;
    [DappRequestType.SignPsbt]: SignEvmTxResponseData;
    [DappRequestType.BatchSignPsbt]: {
        psbts: string[];
    };
    [DappRequestType.SignCkbTx]: SignCkbTxResponseData;
    [DappRequestType.SignCotaNFT]: SignCotaNFTResponseData;
    [DappRequestType.SignCkbRawTx]: SignCkbTxResponseData;
    [DappRequestType.SignNostrEvent]: SignNostrEventData;
    [DappRequestType.EncryptNostrMessage]: any;
    [DappRequestType.DecryptNostrMessage]: any;
    [DappRequestType.AuthMiniApp]: any;
    [DappRequestType.SignMiniAppEvm]: any;
    [DappRequestType.SignMiniAppMessage]: any;
    [DappRequestType.EvmWeb2Login]: EvmWeb2LoginResponse;
}
declare const runPopup: <T extends DappRequestType>(config: PopupConfigOptions<T> & Partial<DappConfig>) => Promise<PopupRerurnType[T]>;

declare const buildJoyIDAuthURL: (request: AuthRequest, type: 'popup' | 'redirect') => string;
declare const authWithRedirect: (request: AuthRequest) => void;
declare const authWithPopup: (request: AuthRequest, config?: Pick<PopupConfigOptions, 'timeoutInSeconds' | 'popup'>) => Promise<AuthResponseData>;
declare const authCallback: (uri?: string) => AuthResponseData;

declare const appendStyle: () => void;
declare const createBlockDialog: <T>(cb: (...args: any[]) => Promise<T>) => Promise<T>;

declare const internalConfig: DappConfig;
declare const initConfig: (config?: DappConfig) => DappConfig;
declare const getConfig: () => DappConfig;

declare class GenericError extends Error {
    error: string;
    error_description: string;
    constructor(error: string, error_description: string);
}
declare class TimeoutError extends GenericError {
    constructor();
}
/**
 * Error thrown when the login popup times out (if the user does not complete auth)
 */
declare class PopupTimeoutError extends TimeoutError {
    popup: Window;
    constructor(popup: Window);
}
declare class PopupCancelledError extends GenericError {
    popup?: Window | undefined;
    constructor(popup?: Window | undefined);
}
declare class PopupNotSupportedError extends GenericError {
    popup: Window;
    constructor(popup: Window);
}
declare class RedirectErrorWithState extends Error {
    message: string;
    state?: any;
    constructor(message: string, state?: any);
}

declare const getRedirectResponse: <T extends {
    state?: any;
}>(uri?: string) => T;
declare const buildJoyIDURL: <T extends BaseRequest>(request: T, type: 'popup' | 'redirect', path: string) => string;
declare const isRedirectFromJoyID: (uri?: string) => boolean;

declare const buildJoyIDSignMessageURL: (request: SignMessageRequest & Record<string, unknown>, type: 'redirect' | 'popup') => string;
declare const signMessageWithRedirect: (request: SignMessageRequest) => void;
declare const signMessageWithPopup: <T extends DappRequestType>(request: SignMessageRequest & Record<string, unknown>, config?: Pick<PopupConfigOptions<T>, "popup" | "timeoutInSeconds"> | undefined) => Promise<SignMessageResponseData>;
declare const signMessageCallback: (uri?: string) => SignMessageResponseData;

export { AASignTypedDataParams, AccessList, AuthRequest, AuthResponse, AuthResponseData, Base64URLString, BaseRequest, BaseSignMessageRequest, BatchSignPsbtRequest, BtcConfig, BtcSignMessageRequest, BtcSignMessageType, CKBTransaction, CellDep, CkbDappConfig, CkbTransactionRequest, CotaNFTTransactionRequest, CredentialKeyType, DappCommunicationType, DappConfig, DappError, DappErrorName, DappRequestType, DappResponse, DepType, EthAddress, EthNetworkConfig, Event, EventKind, EventTemplate, EvmChainParameter, EvmConfig, EvmWeb2LoginConfig, EvmWeb2LoginRequest, EvmWeb2LoginResponse, GenericError, GetPublicKeyRequest, Hash, HashType, Header, Hex, HexNumber, HexString, Input, JoyIDConfig, MiniAppAuthRequest, MiniAppBaseRequest, MiniAppSignEvmTxRequest, MiniAppSignMessageRequest, MiniAppSignTypedDataRequest, Network, OutPoint, Output, PackedSince, PopupCancelledError, PopupConfigOptions, PopupNotSupportedError, PopupRerurnType, PopupTimeoutError, Prettify, RawTransaction, RedirectErrorWithState, RequestNetwork, SESSION_KEY_VER, Script, SessionKeyType, SignCkbRawTxRequest, SignCkbRawTxResponse, SignCkbRawTxResponseData, SignCkbTxRequest, SignCkbTxResponse, SignCkbTxResponseData, SignCotaNFTRequest, SignCotaNFTResponse, SignCotaNFTResponseData, SignEvmResponse, SignEvmTxRequest, SignEvmTxResponseData, SignMessageRequest, SignMessageResponse, SignMessageResponseData, SignNostrEventData, SignNostrEventRequest, SignNostrEventResponse, SignPsbtOptions, SignPsbtRequest, SignTypedDataRequest, SigningAlg, SmartAccountSigner, TimeoutError, TransactionRequest, TypedDataDefinition, UnsignedEvent, WebauthnKeyType, WitnessArgs, append0x, appendBuffer, appendStyle, authCallback, authWithPopup, authWithRedirect, base64URLStringToBuffer, base64urlToHex, bufferToBase64URLString, bufferToHex, bufferToUTF8String, buildJoyIDAuthURL, buildJoyIDSignMessageURL, buildJoyIDURL, createBlockDialog, decodeSearch, encodeSearch, getConfig, getRedirectResponse, hexToArrayBuffer, hexToString, hexToUTF8String, initConfig, internalConfig, isRedirectFromJoyID, isStandaloneBrowser, openPopup, parseSearchWith, remove0x, runPopup, safeExec, signMessageCallback, signMessageWithPopup, signMessageWithRedirect, stringifySearchWith, toSignInput, utf8StringToBuffer };
