/* This file is part of web3.js. web3.js is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. web3.js is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ import { Address } from './qrl_types.js'; import { Bytes, Numbers } from './primitives_types.js'; import { FixedSizeArray } from './utility_types.js'; type _HyperionIndexRange = | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30; export type ConvertToNumber< T extends string, Range extends number = _HyperionIndexRange, > = Range extends unknown ? (`${Range}` extends T ? Range : never) : never; export type Components = { name: string; type: string; indexed?: boolean; components?: Components[]; }; export interface AbiStruct { [key: string]: unknown; name?: string; type: string; } export interface AbiCoderStruct extends AbiStruct { [key: string]: unknown; components?: Array; } // https://docs.soliditylang.org/en/latest/abi-spec.html#json export type AbiParameter = { readonly name: string; readonly type: string; readonly baseType?: string; readonly indexed?: boolean; readonly components?: ReadonlyArray; readonly arrayLength?: number; readonly arrayChildren?: ReadonlyArray; readonly internalType?: string; }; type FragmentTypes = 'constructor' | 'event' | 'function' | 'fallback' | 'receive'; export type AbiBaseFragment = { // type will default to string if passed ABI is declared without "as const" readonly type: string | FragmentTypes; }; // To assign an ABI which is not declared `as const` need to specify a generic string // https://docs.soliditylang.org/en/latest/abi-spec.html#json export type AbiConstructorFragment = AbiBaseFragment & { readonly type: string | 'constructor'; readonly stateMutability: string | 'nonpayable' | 'payable'; readonly inputs?: ReadonlyArray; }; // https://docs.soliditylang.org/en/latest/abi-spec.html#json export type AbiFunctionFragment = AbiBaseFragment & { readonly name: string; readonly type: string | 'function'; readonly stateMutability?: string | 'nonpayable' | 'payable' | 'pure' | 'view'; readonly inputs?: ReadonlyArray; readonly outputs?: ReadonlyArray; readonly constant?: boolean; // stateMutability == 'pure' or stateMutability == 'view' readonly payable?: boolean; // stateMutability == 'payable' }; export type AbiFallbackFragment = AbiBaseFragment & { readonly name: never; readonly type: string | 'fallback'; readonly stateMutability: string | 'nonpayable' | 'payable' | 'pure' | 'view'; readonly inputs: never; readonly outputs: never; // legacy properties readonly constant?: boolean; // stateMutability == 'pure' or stateMutability == 'view' readonly payable?: boolean; // stateMutability == 'payable' }; // https://docs.soliditylang.org/en/latest/abi-spec.html#json export type AbiEventFragment = AbiBaseFragment & { readonly name: string; readonly type: string | 'event'; readonly inputs?: ReadonlyArray; readonly anonymous?: boolean; }; // https://docs.soliditylang.org/en/latest/abi-spec.html#errors export type AbiErrorFragment = AbiBaseFragment & { readonly name: string; readonly type: string | 'error'; readonly inputs?: ReadonlyArray; }; // https://docs.soliditylang.org/en/latest/abi-spec.html#json export type AbiFragment = | AbiConstructorFragment | AbiFunctionFragment | AbiEventFragment | AbiErrorFragment | AbiFallbackFragment; export type ContractAbi = ReadonlyArray; export type AbiInput = | string | AbiParameter | { name: string; type: string; components?: Components; index?: boolean; internalType?: string; } | { readonly [key: string]: unknown }; // https://docs.soliditylang.org/en/develop/abi-spec.html#json export type JsonFunctionInterface = { type: 'function'; name: string; inputs: Components[]; outputs?: AbiInput[]; stateMutability?: string; }; export type JsonEventInterface = { type: 'event'; name: string; inputs: Components[]; indexed: boolean; anonymous: boolean; }; export type FilterAbis = Abi extends Filter ? Abi : never; type _TypedArray = Size extends '' ? Type[] : FixedSizeArray>; export type PrimitiveAddressType = Type extends `address[${infer Size}]` ? _TypedArray : Type extends 'address' ? Address : never; export type PrimitiveStringType = Type extends `string${string}[${infer Size}]` ? _TypedArray : Type extends 'string' | `string${string}` ? string : never; export type PrimitiveBooleanType = Type extends `bool[${infer Size}]` ? _TypedArray : Type extends 'bool' ? boolean : never; export type PrimitiveIntegerType = Type extends | `uint${string}[${infer Size}]` | `int${string}[${infer Size}]` ? _TypedArray : Type extends 'uint' | 'int' | `int${string}` | `uint${string}` ? Numbers : never; export type PrimitiveBytesType = Type extends `bytes${string}[${infer Size}]` ? _TypedArray : Type extends 'bytes' | `bytes${string}` ? Bytes : never; export type PrimitiveTupleType< Type extends string, TypeComponents extends ReadonlyArray | undefined | unknown = [], > = TypeComponents extends ReadonlyArray ? Type extends 'tuple' ? { // eslint-disable-next-line no-use-before-define [Param in TypeComponents[number] as Param['name']]: MatchPrimitiveType< Param['type'], Param['components'] >; } : Type extends `tuple[${infer Size}]` ? _TypedArray< { // eslint-disable-next-line no-use-before-define [Param in TypeComponents[number] as Param['name']]: MatchPrimitiveType< Param['type'], Param['components'] >; }, Size > : never : never; type ObjectToArray = T extends [...infer R, infer A] ? Record & ObjectToArray : T; type ArrToObjectWithFunctions = Array & ObjectToArray; export type MatchPrimitiveType< Type extends string, TypeComponents extends ReadonlyArray | undefined | unknown, > = | PrimitiveAddressType | PrimitiveStringType | PrimitiveBooleanType | PrimitiveIntegerType | PrimitiveBytesType | PrimitiveTupleType | never; type ContractMethodOutputParametersRecursiveArray< Params extends ReadonlyArray | undefined, > = // check if params are empty array Params extends readonly [] ? [] : Params extends readonly [infer H, ...infer R] // check if Params is an array ? H extends AbiParameter ? [ MatchPrimitiveType, ...ContractMethodOutputParametersRecursiveArray, ] : [] : []; type ContractMethodOutputParametersRecursiveRecord< Params extends ReadonlyArray | undefined, > = // check if params are empty array Params extends readonly [] ? [] : Params extends readonly [infer H, ...infer R] // check if Params is an array ? H extends AbiParameter ? H['name'] extends '' // check if output param name is empty string ? ContractMethodOutputParametersRecursiveRecord : Record> & // sets key-value pair of output param name and type ContractMethodOutputParametersRecursiveRecord : ContractMethodOutputParametersRecursiveRecord : Params extends undefined | unknown // param is not array, check if undefined ? [] : Params; export type ContractMethodOutputParameters | undefined> = // check if params are empty array Params extends readonly [] ? void : Params extends readonly [infer H, ...infer R] // check if Params is an array ? R extends readonly [] // if only one output in array ? H extends AbiParameter ? MatchPrimitiveType : [] : // if more than one output ArrToObjectWithFunctions<[...ContractMethodOutputParametersRecursiveArray]> & ContractMethodOutputParametersRecursiveRecord : []; export type ContractMethodInputParameters | undefined> = Params extends readonly [] ? [] : Params extends readonly [infer H, ...infer R] ? H extends AbiParameter ? // TODO: Find a way to set name for tuple item [MatchPrimitiveType, ...ContractMethodInputParameters] : ContractMethodInputParameters : Params extends undefined | unknown ? [] : Params; export type ContractConstructor = { [Abi in FilterAbis as 'constructor']: { readonly Abi: Abi; readonly Inputs: ContractMethodInputParameters; }; }['constructor']; export type ContractConstructorArgs = { [Abi in FilterAbis< Abis, AbiConstructorFragment & { type: 'constructor' } > as 'constructor']: ContractMethodInputParameters; }['constructor']; export type ContractMethod = { readonly Abi: Abi; readonly Inputs: ContractMethodInputParameters; readonly Outputs: ContractMethodOutputParameters; }; export type ContractMethods = { [Abi in FilterAbis< Abis, AbiFunctionFragment & { type: 'function' } > as Abi['name']]: ContractMethod; }; export type ContractEvent = { readonly Abi: Abi; readonly Inputs: ContractMethodInputParameters; }; export type ContractEvents = { [Abi in FilterAbis< Abis, AbiEventFragment & { type: 'event' } > as Abi['name']]: ContractEvent; }; export interface DecodedParams extends Record { __length__: number; }