# ABIType Utilities and type definitions for ABI properties and values, covering the Contract ABI Specification, as well as EIP-712 Typed Data.

ABIType ABIType

Version Version Downloads per month Downloads per month MIT License MIT License GitHub Repo stars GitHub Repo stars Best of JS Best of JS
Strict TypeScript types for Ethereum ABIs. ABIType provides utilities and type definitions for ABI properties and values, covering the [Contract ABI Specification](https://docs.soliditylang.org/en/latest/abi-spec.html), as well as [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data. ```ts twoslash import { AbiParametersToPrimitiveTypes, ExtractAbiFunction } from 'abitype' import { erc20Abi } from 'abitype/abis' type TransferInputTypes = AbiParametersToPrimitiveTypes< // ^? ExtractAbiFunction['inputs'] > ``` Works great for adding blazing fast [autocomplete](https://twitter.com/awkweb/status/1555678944770367493) and type checking to functions, variables, or your own types. No need to generate types with third-party tools – just use your ABI and let TypeScript do the rest! ## TL;DR ABIType might be a good option for your project if: * You want to [typecheck](/api/types) your ABIs or EIP-712 Typed Data. * You want to add type inference and autocomplete to your library based on user-provided ABIs or EIP-712 Typed Data, like [Wagmi](https://wagmi.sh) and [Viem](https://viem.sh). * You need to [convert ABI types](/api/utilities#abiparameterstoprimitivetypes) (e.g. `'string'`) to TypeScript types (e.g. `string`) or other type transformations. * You don’t want to set up a build process to generate types (e.g. TypeChain). ## Install Read the [Getting Started](/guide/getting-started) guide to learn more how to use ABIType. :::code-group ```bash [pnpm] pnpm add abitype ``` ```bash [bun] bun add abitype ``` ```bash [npm] npm i abitype ``` ```bash [yarn] yarn add abitype ``` ::: ## Sponsor If you find ABIType useful, please consider supporting development on [GitHub Sponsors](https://github.com/sponsors/wevm?metadata_campaign=abitype_docs) or sending crypto to `wevm.eth`. Thank you 🙏 ## Community If you have questions or need help, reach out to the community at the [ABIType GitHub Discussions](https://github.com/wevm/abitype/discussions).

Powered by Vercel # Getting Started \[Quickly add ABIType to your TypeScript project] This section will help you start using ABIType in your TypeScript project. You can also try ABIType online in a [TypeScript Playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgUQB4ygQwMYwIIBGwAYgK4B2uwE5ANCulroSRVTQHKYgCmAzvRYAFTFl4weUPgBUIQqKGAxgANx7SAnmH5wAvnABmUCCDgByTERhaeZgFChIsRHEnYATAAYWew8dMWVjYA9BJ8MPZ21tpwZJTKnNw6ALwMGDj4RHHs5Fy8fAA80TwQBq5QHt5E9GYqwDwA7mYAfHbBwXCdAHoA-HDFsWwJuUl8cKkARHwaIAQQADYTcAA+cBPkSUurE5jz8xANmJQ8W2sEu0fYPADyBqcTACY82KC7fPcwEDC7AMqkYGB5hoJnYojY4NIsOQ+AZJABJchgUgwTTaMapYSiJISKSyeSKZRqVH8Ap2TrtOC9frgyFHGHwxHI4nouBQHiYB40IFwADaAANPKgACQIcIKcgAc10fPoRAlwHIMAAumS0kxMqx4tRyEUbKVypUWDV0tDYVAWjyzAqkTA+GYVa0gA). ## Install :::code-group ```bash [pnpm] pnpm add abitype ``` ```bash [bun] bun add abitype ``` ```bash [npm] npm i abitype ``` ```bash [yarn] yarn add abitype ``` ::: :::info[TypeScript Version] ABIType requires `typescript@>=5.0.4`. ::: ## Usage Since ABIs can contain deeply nested arrays and objects, you must either assert ABIs to constants using [`const` assertions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) or use the built-in `narrow` function (works with JavaScript). This allows TypeScript to take the most specific type for expressions and avoid type widening (e.g. no going from `"hello"` to `string`). ```ts const erc20Abi = [...] as const const erc20Abi = [...] ``` ```ts import { narrow } from 'abitype' const erc20Abi = narrow([...]) ``` Once your ABIs are set up correctly, you can use the exported [types](/api/types) and [utilities](/api/utilities) to work with them. You can also import already set-up ABIs from the `abitype/abis` entrypoint to get started quickly. ```ts twoslash import { ExtractAbiFunctionNames } from 'abitype' import { erc20Abi } from 'abitype/abis' type Result = ExtractAbiFunctionNames // ^? ``` ## What's next? After setting up your project with ABIType, you are ready to dive in further! Here are some places to start: * [Learn about the types](/api/types) and [utilities](/api/utilities) available in ABIType. * Follow along with a [walkthrough](/guide/walkthrough) on building a type-safe `readContract` function. # Walkthrough Let's use ABIType to create a type-safe function that calls "read" contract methods. We'll infer function names, argument types, and return types from a user-provided ABI, and make sure it works for function overloads. You can spin up a [TypeScript Playground](https://www.typescriptlang.org/play) to code along. ## 1. Scaffolding `readContract` First, we start off by declaring\[^1] the function `readContract` with some basic types: ```ts twoslash import { Abi } from 'abitype' declare function readContract(config: { abi: Abi functionName: string args: readonly unknown[] }): unknown ``` The function accepts a `config` object which includes the ABI, function name, and arguments. The return type is `unknown` since we don't know what the function will return quite yet.\[^2] Next, let's call the function using the following values: :::code-group ```ts [readContract.ts] twoslash // @filename: abi.ts export const abi = [ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [ { name: 'owner', type: 'address' }, { name: 'collectionId', type: 'uint256' }, ], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'tokenURI', type: 'function', stateMutability: 'pure', inputs: [{ name: 'id', type: 'uint256' }], outputs: [{ name: 'uri', type: 'string' }], }, { name: 'safeTransferFrom', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'tokenId', type: 'uint256' }, ], outputs: [], }, ] as const // @filename: readContract.ts import { Abi } from 'abitype' declare function readContract(config: { abi: Abi functionName: string args: readonly unknown[] }): unknown // ---cut--- import { abi } from './abi' const res = readContract({ abi, functionName: 'balanceOf', args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], }) ``` ```ts [abi.ts] export const abi = [ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [ { name: 'owner', type: 'address' }, { name: 'collectionId', type: 'uint256' }, ], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'tokenURI', type: 'function', stateMutability: 'pure', inputs: [{ name: 'id', type: 'uint256' }], outputs: [{ name: 'uri', type: 'string' }], }, { name: 'safeTransferFrom', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'tokenId', type: 'uint256' }, ], outputs: [], }, ] as const ``` ::: ## 2. Adding inference to `functionName` `functionName` and `args` types aren't inferred from the ABI yet so we can pass any value we want. Let's fix that! Often, you'll want to pull types into [generics](https://www.typescriptlang.org/docs/handbook/2/generics.html) when trying to infer parameters. We'll do the same here, starting with `functionName`: ```ts twoslash // @filename: abi.ts export const abi = [ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [ { name: 'owner', type: 'address' }, { name: 'collectionId', type: 'uint256' }, ], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'tokenURI', type: 'function', stateMutability: 'pure', inputs: [{ name: 'id', type: 'uint256' }], outputs: [{ name: 'uri', type: 'string' }], }, { name: 'safeTransferFrom', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'tokenId', type: 'uint256' }, ], outputs: [], }, ] as const // @filename: readContract.ts // ---cut--- import { Abi, ExtractAbiFunctionNames } from 'abitype' import { abi } from './abi' declare function readContract< abi extends Abi, functionName extends ExtractAbiFunctionNames, >(config: { abi: abi functionName: functionName | ExtractAbiFunctionNames args: readonly unknown[] }): unknown const res = readContract({ abi, functionName: 'balanceOf', // ^? args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], }) ``` First, we create two generics `abi` and `functionName`, and constrain their types. `abi` is set to the `config.abi` property and the `Abi` type. For `functionName`, we import [`ExtractAbiFunctionNames`](/api/utilities#extractabifunctionnames) and use it to parse out all the read function names (state mutability `'pure' | 'view'`\[^3]) from the ABI. Finally, `config.functionName` is set to the user-defined `functionName` and another instance of `ExtractAbiFunctionNames`. This allows us to add the full union (not just the current value) to `functionName`'s scope.\[^4] If you are following along in a TypeScript Playground or editor, you can try various values for `functionName`. `functionName` will autocomplete and only accept `'balanceOf' | 'tokenURI'`. You can also try renaming the function names in `abi` and types will update as well. ```ts twoslash // @noErrors // @filename: abi.ts export const abi = [ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [ { name: 'owner', type: 'address' }, { name: 'collectionId', type: 'uint256' }, ], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'tokenURI', type: 'function', stateMutability: 'pure', inputs: [{ name: 'id', type: 'uint256' }], outputs: [{ name: 'uri', type: 'string' }], }, { name: 'safeTransferFrom', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'tokenId', type: 'uint256' }, ], outputs: [], }, ] as const // @filename: readContract.ts import { Abi, ExtractAbiFunctionNames } from 'abitype' import { abi } from './abi' declare function readContract< abi extends Abi, functionName extends ExtractAbiFunctionNames, >(config: { abi: abi functionName: functionName | ExtractAbiFunctionNames args: readonly unknown[] }): unknown // ---cut--- const res = readContract({ abi, functionName: ' // ^| }) ``` ## 3. Adding inference to `args` With `functionName` complete, we can move on to `args`. This time we don't need to add a generic slot because `args` depends completely on `abi` and `functionName` and doesn't need to infer user input. ```ts twoslash // @filename: abi.ts export const abi = [ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [ { name: 'owner', type: 'address' }, { name: 'collectionId', type: 'uint256' }, ], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'tokenURI', type: 'function', stateMutability: 'pure', inputs: [{ name: 'id', type: 'uint256' }], outputs: [{ name: 'uri', type: 'string' }], }, { name: 'safeTransferFrom', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'tokenId', type: 'uint256' }, ], outputs: [], }, ] as const // @filename: readContract.ts // ---cut--- import { Abi, AbiParametersToPrimitiveTypes, ExtractAbiFunction, ExtractAbiFunctionNames, } from 'abitype' import { abi } from './abi' declare function readContract< abi extends Abi, functionName extends ExtractAbiFunctionNames, >(config: { abi: abi functionName: functionName | ExtractAbiFunctionNames args: AbiParametersToPrimitiveTypes< ExtractAbiFunction['inputs'], 'inputs' > }): unknown const res = readContract({ abi, functionName: 'balanceOf', args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], // ^? }) ``` Since `args`'s type can be completely defined inline, we import [`ExtractAbiFunction`](/api/utilities#extractabifunction) and [`AbiParametersToPrimitiveTypes`](/api/utilities#abiparameterstoprimitivetypes) and wire them up. First, we use `ExtractAbiFunction` to get the function from the ABI that matches `functionName`. Then, we use `AbiParametersToPrimitiveTypes` to convert the function's inputs to their TypeScript primitive types. For `abi`, you'll notice there are two `'balanceOf'` functions. This means `'balanceOf'` is overloaded on the contract. The cool thing about TypeScript is that we can still infer the correct types for overloaded functions (e.g. union like ``readonly [`0x${string}`] | readonly [`0x${string}`, bigint]``)! This uses a TypeScript feature called [distributivity](https://jser.dev/typescript/2023/01/22/distributiveness-in-ts.html) and is worth learning more about if you're interested. ## 4. Adding the return type Finally, we can add the return type: ```ts twoslash // @filename: abi.ts export const abi = [ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [ { name: 'owner', type: 'address' }, { name: 'collectionId', type: 'uint256' }, ], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'tokenURI', type: 'function', stateMutability: 'pure', inputs: [{ name: 'id', type: 'uint256' }], outputs: [{ name: 'uri', type: 'string' }], }, { name: 'safeTransferFrom', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'tokenId', type: 'uint256' }, ], outputs: [], }, ] as const // @filename: readContract.ts // ---cut--- import { Abi, AbiFunction, AbiParametersToPrimitiveTypes, ExtractAbiFunction, ExtractAbiFunctionNames, } from 'abitype' import { abi } from './abi' declare function readContract< abi extends Abi, functionName extends ExtractAbiFunctionNames, abiFunction extends AbiFunction = ExtractAbiFunction, >(config: { abi: abi functionName: functionName | ExtractAbiFunctionNames args: AbiParametersToPrimitiveTypes }): AbiParametersToPrimitiveTypes const res = readContract({ // ^? abi, functionName: 'balanceOf', args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], }) ``` We can refactor our `ExtractAbiFunction` call into a generic slot `abiFunction` (of type [`AbiFunction`](/api/types#abifunction)) and set the default to the result of `ExtractAbiFunction`. This allows us to use `abiFunction` in for `args` and the return type. Lastly, we wire up another `AbiParametersToPrimitiveTypes` call for the return type—this time using outputs. ## 5. Wrapping up `readContract`'s types are starting to look solid! It infers the correct types for `functionName` and `args` based on the ABI (and works with overloaded functions). It also infers the correct return type based on the ABI and `functionName`. The only thing left is to implement the function itself. There are a few other ways to improve the typing that are out of scope for this walkthrough, but are worth noting: * `abi` requires a const assertion to ensure TypeScript takes the most specific type, but you can set things up so this is unnecessary for inline `abi` definitions. * `args` can be an empty array if the function doesn't take any arguments, but you could conditionally add `args` to `config` if it's not empty. * `readContract`'s return type is an array, but you could unwrap it if the function only has one output or transform it to another type depending on your implementation. The preceding points are all implemented in throughout the [examples](https://github.com/wevm/abitype/tree/main/playgrounds) in this directory so check them out if you're interested. \[^1]: We use the `declare` keyword so we don't need to worry about the implementation. In this case, the implementation would look something like encoding arguments and sending with the [`eth_call`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call) RPC method. \[^2]: If this was a real function that read via RPC, we'd likely want to make it `async` and return a `Promise`, but we'll leave that out for simplicity. \[^3]: We could add or change this to `'nonpayable' | 'payable'` to allow write functions. \[^4]: Try removing `| ExtractAbiFunctionNames` from `functionName`, hover over `functionName` in your editor, and see what happens. You'll notice that the only `functionName` that shows up in the current value. # Types Types covering the [Contract ABI](https://docs.soliditylang.org/en/latest/abi-spec.html#json) and [EIP-712 Typed Data](https://eips.ethereum.org/EIPS/eip-712#definition-of-typed-structured-data-%F0%9D%95%8A) Specifications. ## `Abi` Type matching the [Contract ABI Specification](https://docs.soliditylang.org/en/latest/abi-spec.html#json) ```ts twoslash noplayground import { Abi } from 'abitype' ``` ## `AbiConstructor` ABI [Constructor](https://docs.soliditylang.org/en/latest/abi-spec.html#json) type ```ts twoslash noplayground import { AbiConstructor } from 'abitype' ``` ## `AbiError` ABI [Error](https://docs.soliditylang.org/en/latest/abi-spec.html#errors) type ```ts twoslash noplayground import { AbiError } from 'abitype' ``` ## `AbiEvent` ABI [Event](https://docs.soliditylang.org/en/latest/abi-spec.html#events) type ```ts twoslash noplayground import { AbiEvent } from 'abitype' ``` ## `AbiFallback` ABI [Fallback](https://docs.soliditylang.org/en/latest/abi-spec.html#json) type ```ts twoslash noplayground import { AbiFallback } from 'abitype' ``` ## `AbiFunction` ABI [Function](https://docs.soliditylang.org/en/latest/abi-spec.html#json) type ```ts twoslash noplayground import { AbiFunction } from 'abitype' ``` ## `AbiInternalType` Representation used by Solidity compiler (e.g. `'string'`, `'int256'`, `'struct Foo'`) ```ts twoslash noplayground import { AbiInternalType } from 'abitype' ``` ## `AbiItemType` `"type"` name for [`Abi`](#abi) items (e.g. `'type': 'function'` for [`AbiFunction`](#abifunction)) ```ts twoslash noplayground import { AbiItemType } from 'abitype' ``` ## `AbiParameter` `inputs` and `outputs` item for ABI functions, errors, and constructors ```ts twoslash noplayground import { AbiParameter } from 'abitype' ``` ## `AbiEventParameter` `inputs` for ABI events ```ts twoslash noplayground import { AbiEventParameter } from 'abitype' ``` ## `AbiParameterKind` Kind of ABI parameter: `'inputs' | 'outputs'` ```ts twoslash noplayground import { AbiParameterKind } from 'abitype' ``` ## `AbiReceive` ABI [Receive](https://docs.soliditylang.org/en/latest/contracts.html#receive-ether-function) type ```ts twoslash noplayground import { AbiReceive } from 'abitype' ``` ## `AbiStateMutability` ABI Function behavior ```ts twoslash noplayground import { AbiStateMutability } from 'abitype' ``` ## `AbiType` ABI canonical [types](https://docs.soliditylang.org/en/latest/abi-spec.html#json) ```ts twoslash noplayground import { AbiType } from 'abitype' ``` ## Solidity types [Solidity types](https://docs.soliditylang.org/en/latest/abi-spec.html#types) as template strings ```ts twoslash noplayground import { SolidityAddress, SolidityArray, SolidityBool, SolidityBytes, SolidityFunction, SolidityInt, SolidityString, SolidityTuple, } from 'abitype' ``` ## `TypedData` [EIP-712](https://eips.ethereum.org/EIPS/eip-712#definition-of-typed-structured-data-%F0%9D%95%8A) Typed Data Specification ```ts twoslash noplayground import { TypedData } from 'abitype' ``` ## `TypedDataDomain` [EIP-712](https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator) Domain ```ts twoslash noplayground import { TypedDataDomain } from 'abitype' ``` ## `TypedDataParameter` Entry in `TypedData` type items ```ts twoslash noplayground import { TypedDataParameter } from 'abitype' ``` ## `TypedDataType` Subset of `AbiType` that excludes `tuple` and `function` ```ts twoslash noplayground import { TypedDataType } from 'abitype' ``` # Utilities Utility types for working with ABIs and EIP-712 Typed Data. ## `AbiParameterToPrimitiveType` Converts `AbiParameter` to corresponding TypeScript primitive type. | Name | Description | Type | | ------------------ | -------------------------------------------------- | ----------------------------- | | `abiParameter` | Parameter to convert to TypeScript representation. | `AbiParameter` | | `abiParameterKind` | Kind to narrow by parameter type. | `AbiParameterKind` (optional) | | returns | TypeScript primitive type. | `type` (inferred) | #### Example ```ts twoslash import { AbiParameterToPrimitiveType } from 'abitype' type Result = AbiParameterToPrimitiveType<{ // ^? name: 'owner' type: 'address' }> ``` ## `AbiParametersToPrimitiveTypes` Converts array of `AbiParameter` to corresponding TypeScript primitive types. | Name | Description | Type | | ------------------ | ---------------------------------------------------- | ----------------------------- | | `abiParameters` | Parameters to convert to TypeScript representations. | `readonly AbiParameter[]` | | `abiParameterKind` | Kind to narrow by parameter type. | `AbiParameterKind` (optional) | | returns | TypeScript primitive types. | `type[]` (inferred) | #### Example ```ts twoslash import { AbiParametersToPrimitiveTypes } from 'abitype' type Result = AbiParametersToPrimitiveTypes< // ^? [{ name: 'to'; type: 'address' }, { name: 'tokenId'; type: 'uint256' }] > ``` ## `AbiTypeToPrimitiveType` Converts `AbiType` to corresponding TypeScript primitive type. | Name | Description | Type | | ------------------ | ------------------------------------------------- | ----------------------------- | | `abiType` | ABI type to convert to TypeScript representation. | `AbiType` | | `abiParameterKind` | Kind to narrow by parameter type. | `AbiParameterKind` (optional) | | returns | TypeScript primitive type. | `type` (inferred) | :::info[NOTE] Does not include full array or tuple conversion. Use [`AbiParameterToPrimitiveType`](#abiparametertoprimitivetype) to fully convert array and tuple types. ::: #### Example ```ts twoslash import { AbiTypeToPrimitiveType } from 'abitype' type Result = AbiTypeToPrimitiveType<'address'> // ^? ``` ## `ExtractAbiError` Extracts `AbiError` with name from `Abi`. | Name | Description | Type | | ----------- | -------------- | ------------------- | | `abi` | ABI. | `Abi` | | `errorName` | Name of error. | `string` (inferred) | | returns | ABI Error. | `AbiError` | #### Example ```ts twoslash import { ExtractAbiError } from 'abitype' const abi = [ { name: 'BarError', type: 'error', inputs: [] }, { name: 'FooError', type: 'error', inputs: [] }, ] as const type Result = ExtractAbiError // ^? ``` ## `ExtractAbiErrorNames` Extracts all `AbiError` names from `Abi`. | Name | Description | Type | | ------- | ---------------- | ------------------- | | `abi` | ABI. | `Abi` | | returns | ABI Error names. | `string` (inferred) | #### Example ```ts twoslash import { ExtractAbiErrorNames } from 'abitype' const abi = [ { name: 'FooError', type: 'error', inputs: [] }, { name: 'BarError', type: 'error', inputs: [] }, ] as const type Result = ExtractAbiErrorNames // ^? ``` ## `ExtractAbiErrors` Extracts all `AbiError` types from `Abi`. | Name | Description | Type | | ------- | ----------- | ------------------ | | `abi` | ABI. | `Abi` | | returns | ABI Errors. | `AbiError` (union) | #### Example ```ts twoslash import { ExtractAbiErrors } from 'abitype' const abi = [ { name: 'FooError', type: 'error', inputs: [] }, { name: 'BarError', type: 'error', inputs: [] }, ] as const type Result = ExtractAbiErrors // ^? ``` ## `ExtractAbiEvent` Extracts `AbiEvent` with name from `Abi`. | Name | Description | Type | | ----------- | -------------- | ------------------- | | `abi` | ABI. | `Abi` | | `eventName` | Name of event. | `string` (inferred) | | returns | ABI Event. | `AbiEvent` | #### Example ```ts twoslash import { ExtractAbiEvent } from 'abitype' const abi = [ { name: 'Approval', type: 'event', anonymous: false, inputs: [ { name: 'owner', type: 'address', indexed: true }, { name: 'approved', type: 'address', indexed: true }, { name: 'tokenId', type: 'uint256', indexed: true }, ], }, { name: 'Transfer', type: 'event', anonymous: false, inputs: [ { name: 'from', type: 'address', indexed: true }, { name: 'to', type: 'address', indexed: true }, { name: 'tokenId', type: 'uint256', indexed: true }, ], }, ] as const type Result = ExtractAbiEvent // ^? ``` ## `ExtractAbiEventNames` Extracts all `AbiEvent` names from `Abi`. | Name | Description | Type | | ------- | ---------------- | ------------------- | | `abi` | ABI. | `Abi` | | returns | ABI Error names. | `string` (inferred) | #### Example ```ts twoslash import { ExtractAbiEventNames } from 'abitype' const abi = [ { name: 'Approval', type: 'event', anonymous: false, inputs: [ { name: 'owner', type: 'address', indexed: true }, { name: 'approved', type: 'address', indexed: true }, { name: 'tokenId', type: 'uint256', indexed: true }, ], }, { name: 'Transfer', type: 'event', anonymous: false, inputs: [ { name: 'from', type: 'address', indexed: true }, { name: 'to', type: 'address', indexed: true }, { name: 'tokenId', type: 'uint256', indexed: true }, ], }, ] as const type Result = ExtractAbiEventNames // ^? ``` ## `ExtractAbiEvents` Extracts all `AbiEvent` types from `Abi`. | Name | Description | Type | | ------- | ----------- | ------------------ | | `abi` | ABI. | `Abi` | | returns | ABI Events. | `AbiEvent` (union) | #### Example ```ts twoslash import { ExtractAbiEvents } from 'abitype' const abi = [ { name: 'Approval', type: 'event', anonymous: false, inputs: [ { name: 'owner', type: 'address', indexed: true }, { name: 'approved', type: 'address', indexed: true }, { name: 'tokenId', type: 'uint256', indexed: true }, ], }, { name: 'Transfer', type: 'event', anonymous: false, inputs: [ { name: 'from', type: 'address', indexed: true }, { name: 'to', type: 'address', indexed: true }, { name: 'tokenId', type: 'uint256', indexed: true }, ], }, ] as const type Result = ExtractAbiEvents // ^? ``` ## `ExtractAbiFunction` Extracts `AbiFunction` with name from `Abi`. | Name | Description | Type | | -------------------- | --------------------- | ------------------------------- | | `abi` | ABI. | `Abi` | | `functionName` | Name of function. | `string` (inferred) | | `abiStateMutability` | ABI state mutability. | `AbiStateMutability` (optional) | | returns | ABI Function. | `AbiFunction` | #### Example ```ts twoslash import { ExtractAbiFunction } from 'abitype' const abi = [ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'safeTransferFrom', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'tokenId', type: 'uint256' }, ], outputs: [], }, ] as const type Result = ExtractAbiFunction // ^? ``` ## `ExtractAbiFunctionNames` Extracts all `AbiFunction` names from `Abi`. | Name | Description | Type | | -------------------- | --------------------- | ------------------------------- | | `abi` | ABI. | `Abi` | | `abiStateMutability` | ABI state mutability. | `AbiStateMutability` (optional) | | returns | ABI Event names. | `string` (inferred) | #### Example ```ts twoslash import { ExtractAbiFunctionNames } from 'abitype' const abi = [ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'safeTransferFrom', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'tokenId', type: 'uint256' }, ], outputs: [], }, ] as const type Result = ExtractAbiFunctionNames // ^? ``` ## `ExtractAbiFunctions` Extracts all `AbiFunction` types from `Abi`. | Name | Description | Type | | ------- | -------------- | --------------------- | | `abi` | ABI. | `Abi` | | returns | ABI Functions. | `AbiFunction` (union) | #### Example ```ts twoslash import { ExtractAbiFunctions } from 'abitype' const abi = [ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'safeTransferFrom', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'tokenId', type: 'uint256' }, ], outputs: [], }, ] as const type Result = ExtractAbiFunctions // ^? ``` By default, extracts all functions, but you can also filter by `AbiStateMutability`: ```ts type Result = ExtractAbiFunctions ``` ## `IsAbi` Checks if type is `Abi`. | Name | Description | Type | | ------- | ----------------------------------------------------- | --------- | | `abi` | ABI. | `Abi` | | returns | Boolean value. `true` if valid `Abi`, `false` if not. | `boolean` | #### Example ```ts twoslash import { IsAbi } from 'abitype' const abi = [ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ name: 'balance', type: 'uint256' }], }, { name: 'safeTransferFrom', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'tokenId', type: 'uint256' }, ], outputs: [], }, ] as const type Result = IsAbi // ^? ``` ## `IsTypedData` Checks if type is `TypedData`. | Name | Description | Type | | ----------- | ----------------------------------------------------------- | ----------- | | `typedData` | EIP-712 Typed Data schema. | `TypedData` | | returns | Boolean value. `true` if valid `TypedData`, `false` if not. | `boolean` | #### Example ```ts twoslash import { IsTypedData } from 'abitype' const types = { Person: [ { name: 'name', type: 'string' }, { name: 'wallet', type: 'address' }, ], Mail: [ { name: 'from', type: 'Person' }, { name: 'to', type: 'Person' }, { name: 'contents', type: 'string' }, ], } as const type Result = IsTypedData // ^? ``` ## `TypedDataToPrimitiveTypes` Converts [EIP-712](https://eips.ethereum.org/EIPS/eip-712#definition-of-typed-structured-data-%F0%9D%95%8A) `TypedData` to corresponding TypeScript primitive type. | Name | Description | Type | | ----------- | ------------------------------------ | ------------------------------------- | | `typedData` | EIP-712 Typed Data schema. | `TypedData` | | returns | TypeScript representation of schema. | `{ [name: string]: type }` (inferred) | #### Example ```ts twoslash import { TypedDataToPrimitiveTypes } from 'abitype' const types = { Person: [ { name: 'name', type: 'string' }, { name: 'wallet', type: 'address' }, ], Mail: [ { name: 'from', type: 'Person' }, { name: 'to', type: 'Person' }, { name: 'contents', type: 'string' }, ], } as const type Result = TypedDataToPrimitiveTypes // ^? ``` # Test \[Entrypoint for test utilities and constants] ABIType exports some test utilities and constants to make playing around and testing your code easier via the `'abitype/abis'` entrypoint. ### ABIs ```ts twoslash import { customSolidityErrorsAbi, ensAbi, ensRegistryWithFallbackAbi, erc20Abi, nestedTupleArrayAbi, nounsAuctionHouseAbi, seaportAbi, wagmiMintExampleAbi, wethAbi, writingEditionsFactoryAbi, eip165Abi, } from 'abitype/abis' ``` ### Human-Readable ABIs ```ts twoslash import { customSolidityErrorsHumanReadableAbi, ensHumanReadableAbi, ensRegistryWithFallbackHumanReadableAbi, erc20HumanReadableAbi, nestedTupleArrayHumanReadableAbi, nounsAuctionHouseHumanReadableAbi, seaportHumanReadableAbi, wagmiMintExampleHumanReadableAbi, wethHumanReadableAbi, writingEditionsFactoryHumanReadableAbi, } from 'abitype/abis' ``` # Configuration How to configure ABIType in userland or as a library author. ## Overview ABIType's types are customizable using [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html). Just install `abitype` (make sure versions match) and extend the `Register` interface either directly in your code or in a `d.ts` file (e.g. `abi.d.ts`): ```ts twoslash import 'abitype' // ---cut--- declare module 'abitype' { export interface Register { bigIntType: bigint & { foo: 'bar' } } } import { ResolvedRegister } from 'abitype' type Result = ResolvedRegister['bigIntType'] // ^? ``` :::info[Extending Config from third-party packages] If you are using ABIType via another package (e.g. [`viem`](https://viem.sh)), you can customize the ABIType's types by targeting the package's `abitype` module: ```ts declare module 'viem/node_modules/abitype' { export interface Register { bigIntType: MyCustomBigIntType } } ``` ::: ## Options ABIType tries to strike a balance between type exhaustiveness and speed with sensible defaults. In some cases, you might want to tune your configuration (e.g. use a custom `bigint` type). To do this, the following configuration options are available: :::warning When configuring `arrayMaxDepth`, `fixedArrayMinLength`, and `fixedArrayMaxLength`, there are trade-offs. For example, choosing a non-false value for `arrayMaxDepth` and increasing the range between `fixedArrayMinLength` and `fixedArrayMaxLength` will make your types more exhaustive, but will also slow down the compiler for type checking, autocomplete, etc. ::: ### `addressType` TypeScript type to use for `address` values. * Type `any` * Default `` `0x${string}` `` ```ts twoslash import 'abitype' // ---cut--- declare module 'abitype' { export interface Register { addressType: `0x${string}` } } ``` ### `arrayMaxDepth` Maximum depth for nested array types (e.g. `string[][]`). When `false`, there is no maximum array depth. * Type `number | false` * Default `false` ```ts twoslash import 'abitype' // ---cut--- declare module 'abitype' { export interface Register { arrayMaxDepth: false } } ``` ### `bigIntType` TypeScript type to use for `int` and `uint` values, where `M > 48`. * Type `any` * Default `bigint` ```ts twoslash import 'abitype' // ---cut--- declare module 'abitype' { export interface Register { bigIntType: bigint } } ``` ### `bytesType` TypeScript type to use for `bytes` values. * Type `{ inputs: any; outputs: any }` * Default ``{ inputs: `0x${string}` | Uint8Array; outputs: `0x${string}` }`` ```ts twoslash import 'abitype' // ---cut--- declare module 'abitype' { export interface Register { bytesType: { inputs: `0x${string}` outputs: `0x${string}` } } } ``` ### `fixedArrayMinLength` Lower bound for fixed-length arrays. * Type `number` * Default `1` ```ts twoslash import 'abitype' // ---cut--- declare module 'abitype' { export interface Register { fixedArrayMinLength: 1 } } ``` ### `fixedArrayMaxLength` Upper bound for fixed-length arrays. * Type `number` * Default `99` ```ts twoslash import 'abitype' // ---cut--- declare module 'abitype' { export interface Register { fixedArrayMaxLength: 99 } } ``` ### `intType` TypeScript type to use for `int` and `uint` values, where `M <= 48`. * Type `any` * Default `number` ```ts twoslash import 'abitype' // ---cut--- declare module 'abitype' { export interface Register { intType: number } } ``` ### `experimental_namedTuples` Enables named tuple generation in [`AbiParametersToPrimitiveTypes`](/api/utilities#abiparameterstoprimitivetypes) for common ABI parameter names. * Type `boolean` * Default `false` ```ts twoslash import 'abitype' // ---cut--- declare module 'abitype' { export interface Register { experimental_namedTuples: false } } ``` ### `strictAbiType` When set, validates `AbiParameter`'s `type` against `AbiType`. * Type `boolean` * Default `false` ```ts twoslash import 'abitype' // ---cut--- declare module 'abitype' { export interface Register { strictAbiType: false } } ``` :::warning You probably only want to set this to `true` if parsed types are returning as `unknown` and you want to figure out why. This will slow down type checking significantly. :::