import basex from 'base-x';
import { keccak_256 } from '@noble/hashes/sha3';
import { blake2b } from '@noble/hashes/blake2b';

declare function encodeSubstrateAddress(key: Uint8Array | string | bigint, ss58Format?: number): string;
declare function decodeSubstrateAddress(address: string, ignoreChecksum?: boolean, ss58Format?: number): DecodeSubstrateAddressResult;

declare type SubAddressObj = {
    Substrate: string;
};
declare type SubAddressObjUncapitalized = {
    substrate: string;
};
declare type EthAddressObj = {
    Ethereum: string;
};
declare type EthAddressObjUncapitalized = {
    ethereum: string;
};
declare type CrossAccountId = SubAddressObj & {
    Ethereum?: never;
} | EthAddressObj & {
    Substrate?: never;
};
declare type CrossAccountIdUncapitalized = SubAddressObjUncapitalized & {
    ethereum?: never;
} | EthAddressObjUncapitalized & {
    substrate?: never;
};

declare const vec2str: (arr: Array<number | string>) => string;
declare const str2vec: (str: string) => number[];
declare const strToU8a: (str: string) => Uint8Array;
declare const hexToU8a: (hexString: string) => Uint8Array;
declare const u8aToHex: (bytes: number[] | Uint8Array) => string;
declare const hexStringToString: (hexString: string) => string;
declare const safeJsonParseStringOrHexString: <T = any>(stringOrHexString: string) => string | T;
declare const parseAndCheckTheNumberIsDWORD: (n: number | string) => number;
declare const DWORDHexString: {
    fromNumber: (n: number) => string;
    toNumber: (s: string) => number;
};

declare const StringUtils_vec2str: typeof vec2str;
declare const StringUtils_str2vec: typeof str2vec;
declare const StringUtils_strToU8a: typeof strToU8a;
declare const StringUtils_hexToU8a: typeof hexToU8a;
declare const StringUtils_u8aToHex: typeof u8aToHex;
declare const StringUtils_hexStringToString: typeof hexStringToString;
declare const StringUtils_safeJsonParseStringOrHexString: typeof safeJsonParseStringOrHexString;
declare const StringUtils_parseAndCheckTheNumberIsDWORD: typeof parseAndCheckTheNumberIsDWORD;
declare const StringUtils_DWORDHexString: typeof DWORDHexString;
declare namespace StringUtils {
  export {
    StringUtils_vec2str as vec2str,
    StringUtils_str2vec as str2vec,
    StringUtils_strToU8a as strToU8a,
    StringUtils_hexToU8a as hexToU8a,
    StringUtils_u8aToHex as u8aToHex,
    StringUtils_hexStringToString as hexStringToString,
    StringUtils_safeJsonParseStringOrHexString as safeJsonParseStringOrHexString,
    StringUtils_parseAndCheckTheNumberIsDWORD as parseAndCheckTheNumberIsDWORD,
    StringUtils_DWORDHexString as DWORDHexString,
  };
}

declare const base58: basex.BaseConverter;
declare const base64: basex.BaseConverter;

declare const algorithms_keccak_256: typeof keccak_256;
declare const algorithms_blake2b: typeof blake2b;
declare const algorithms_base58: typeof base58;
declare const algorithms_base64: typeof base64;
declare const algorithms_basex: typeof basex;
declare namespace algorithms {
  export {
    algorithms_keccak_256 as keccak_256,
    algorithms_blake2b as blake2b,
    algorithms_base58 as base58,
    algorithms_base64 as base64,
    algorithms_basex as basex,
  };
}

declare const STATIC_ADDRESSES: {
    readonly contractHelpers: "0x842899ECF380553E8a4de75bF534cdf6fBF64049";
    readonly collectionHelpers: "0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F";
};
declare const NESTING_PREFIX: "0xf8238ccfff8ed887463fd5e0";
declare const COLLECTION_ADDRESS_PREFIX: "0x17c4e6453cc49aaaaeaca894e6d9683e";

declare const constants_STATIC_ADDRESSES: typeof STATIC_ADDRESSES;
declare const constants_NESTING_PREFIX: typeof NESTING_PREFIX;
declare const constants_COLLECTION_ADDRESS_PREFIX: typeof COLLECTION_ADDRESS_PREFIX;
declare namespace constants {
  export {
    constants_STATIC_ADDRESSES as STATIC_ADDRESSES,
    constants_NESTING_PREFIX as NESTING_PREFIX,
    constants_COLLECTION_ADDRESS_PREFIX as COLLECTION_ADDRESS_PREFIX,
  };
}

declare type DecodeSubstrateAddressResult = {
    u8a: Uint8Array;
    hex: string;
    bigint: bigint;
};
declare const validate: {
    substrateAddress: (address: string) => boolean;
    ethereumAddress: (address: string) => boolean;
    collectionAddress: (address: string) => boolean;
    nestingAddress: (address: string) => boolean;
    collectionId: (collectionId: number) => boolean;
    tokenId: (tokenId: number) => boolean;
};
declare const is: {
    substrateAddress: (address: string) => boolean;
    ethereumAddress: (address: string) => boolean;
    collectionAddress: (address: string) => boolean;
    nestingAddress: (address: string) => boolean;
    collectionId: (collectionId: number) => boolean;
    tokenId: (tokenId: number) => boolean;
    crossAccountId(obj: any): obj is CrossAccountId;
    crossAccountIdUncapitalized(obj: any): obj is CrossAccountIdUncapitalized;
    substrateAddressObject(obj: any): obj is SubAddressObj;
    ethereumAddressObject(obj: any): obj is EthAddressObj;
    substrateAddressObjectUncapitalized(obj: any): obj is SubAddressObjUncapitalized;
    ethereumAddressObjectUncapitalized(obj: any): obj is EthAddressObjUncapitalized;
};
declare const collection: {
    idToAddress: (collectionId: number) => string | null;
    addressToId: (address: string) => number | null;
};
declare const nesting: {
    idsToAddress: (collectionId: number, tokenId: number) => string;
    addressToIds: (address: string) => {
        collectionId: number;
        tokenId: number;
    };
};
declare const to: {
    crossAccountId: (address: string) => CrossAccountId;
    crossAccountIdNormalized: (address: string) => CrossAccountId;
    substrateNormalizedOrMirrorIfEthereum: (address: string) => string;
};
declare const extract: {
    normalizedAddressFromObject: (address: string | object) => string;
    normalizedAddressFromObjectSafe: (address: string | object) => string | null;
    crossAccountIdFromObject: (obj: any) => CrossAccountId;
    crossAccountIdFromObjectNormalized: (obj: any) => CrossAccountId;
};
declare const mirror: {
    substrateToEthereum: (address: string, ignoreChecksum?: boolean | undefined) => string;
    ethereumToSubstrate: (evmAddress: string, ss58Format?: number) => string;
};
declare const normalize: {
    substrateAddress: (address: string, prefix?: number) => string;
    ethereumAddress: (address: string) => string;
};
declare const compare: {
    substrateAddresses: (address1: string | object | {
        Substrate: string;
    }, address2: string | object | {
        Substrate: string;
    }) => boolean;
    ethereumAddresses: (address1: string | object | {
        Ethereum: string;
    }, address2: string | object | {
        Ethereum: string;
    }) => boolean;
};
declare const substrate: {
    encode: typeof encodeSubstrateAddress;
    decode: typeof decodeSubstrateAddress;
    compare: (address1: string | object | {
        Substrate: string;
    }, address2: string | object | {
        Substrate: string;
    }) => boolean;
};
declare const Address: {
    constants: typeof constants;
    is: {
        substrateAddress: (address: string) => boolean;
        ethereumAddress: (address: string) => boolean;
        collectionAddress: (address: string) => boolean;
        nestingAddress: (address: string) => boolean;
        collectionId: (collectionId: number) => boolean;
        tokenId: (tokenId: number) => boolean;
        crossAccountId(obj: any): obj is CrossAccountId;
        crossAccountIdUncapitalized(obj: any): obj is CrossAccountIdUncapitalized;
        substrateAddressObject(obj: any): obj is SubAddressObj;
        ethereumAddressObject(obj: any): obj is EthAddressObj;
        substrateAddressObjectUncapitalized(obj: any): obj is SubAddressObjUncapitalized;
        ethereumAddressObjectUncapitalized(obj: any): obj is EthAddressObjUncapitalized;
    };
    validate: {
        substrateAddress: (address: string) => boolean;
        ethereumAddress: (address: string) => boolean;
        collectionAddress: (address: string) => boolean;
        nestingAddress: (address: string) => boolean;
        collectionId: (collectionId: number) => boolean;
        tokenId: (tokenId: number) => boolean;
    };
    collection: {
        idToAddress: (collectionId: number) => string | null;
        addressToId: (address: string) => number | null;
    };
    nesting: {
        idsToAddress: (collectionId: number, tokenId: number) => string;
        addressToIds: (address: string) => {
            collectionId: number;
            tokenId: number;
        };
    };
    to: {
        crossAccountId: (address: string) => CrossAccountId;
        crossAccountIdNormalized: (address: string) => CrossAccountId;
        substrateNormalizedOrMirrorIfEthereum: (address: string) => string;
    };
    extract: {
        normalizedAddressFromObject: (address: string | object) => string;
        normalizedAddressFromObjectSafe: (address: string | object) => string | null;
        crossAccountIdFromObject: (obj: any) => CrossAccountId;
        crossAccountIdFromObjectNormalized: (obj: any) => CrossAccountId;
    };
    mirror: {
        substrateToEthereum: (address: string, ignoreChecksum?: boolean | undefined) => string;
        ethereumToSubstrate: (evmAddress: string, ss58Format?: number) => string;
    };
    normalize: {
        substrateAddress: (address: string, prefix?: number) => string;
        ethereumAddress: (address: string) => string;
    };
    compare: {
        substrateAddresses: (address1: string | object | {
            Substrate: string;
        }, address2: string | object | {
            Substrate: string;
        }) => boolean;
        ethereumAddresses: (address1: string | object | {
            Ethereum: string;
        }, address2: string | object | {
            Ethereum: string;
        }) => boolean;
    };
    substrate: {
        encode: typeof encodeSubstrateAddress;
        decode: typeof decodeSubstrateAddress;
        compare: (address1: string | object | {
            Substrate: string;
        }, address2: string | object | {
            Substrate: string;
        }) => boolean;
    };
    algorithms: typeof algorithms;
    StringUtils: typeof StringUtils;
};

export { Address, DecodeSubstrateAddressResult, StringUtils, algorithms, collection, compare, constants, extract, is, mirror, nesting, normalize, substrate, to, validate };
