Strict TypeScript types for Ethereum ABIs. ABIType provides utilities and type definitions for ABI properties and values, covering the Contract ABI Specification, as well as EIP-712 Typed Data.
import { ExtractAbiFunctions } from 'abitype'
const erc721Abi = [...] as const
type Result = ExtractAbiFunctions<typeof erc721Abi, 'payable'>
Works great for adding blazing fast autocomplete and type checking to functions, variables, or your own types (examples). No need to generate types with third-party tools – just use your ABI and let TypeScript do the rest!
npm install abitype
pnpm add abitype
yarn add abitype
ABIType requires typescript@>=4.9.4
Since ABIs can contain deeply nested arrays and objects, you must either assert ABIs to constants using const
assertions or use the built-in narrow
function (works with JavaScript). This allows TypeScript to take the most specific types for expressions and avoid type widening (e.g. no going from "hello"
to string
).
const erc721Abi = [...] as const
const erc721Abi = <const>[...]
import { narrow } from 'abitype'
const erc721Abi = narrow([...])
ABIType might be a good option for your project if:
- You want to typecheck 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.
- You need to convert ABI types (e.g.
'string'
) to TypeScript types (e.g.string
) or other type transformations. - You need to validate ABIs at runtime (e.g. after fetching from external resource).
- You don’t want to set up a build process to generate types (e.g. TypeChain).
Converts AbiParameter
to corresponding TypeScript primitive type.
Name | Description | Type |
---|---|---|
TAbiParameter |
Parameter to convert to TypeScript representation. | AbiParameter |
TAbiParameterKind |
Kind to narrow by parameter type. | AbiParameterKind (optional) |
returns | TypeScript primitive type. | TType (inferred) |
import { AbiParameterToPrimitiveType } from 'abitype'
type Result = AbiParameterToPrimitiveType<{
name: 'owner'
type: 'address'
}>
Converts array of AbiParameter
to corresponding TypeScript primitive types.
Name | Description | Type |
---|---|---|
TAbiParameters |
Parameters to convert to TypeScript representations. | readonly AbiParameter[] |
TAbiParameterKind |
Kind to narrow by parameter type. | AbiParameterKind (optional) |
returns | TypeScript primitive types. | TType[] (inferred) |
import { AbiParametersToPrimitiveTypes } from 'abitype'
type Result = AbiParametersToPrimitiveTypes<
[
{
name: 'to'
type: 'address'
},
{
name: 'tokenId'
type: 'uint256'
},
]
>
Converts AbiType
to corresponding TypeScript primitive type.
Name | Description | Type |
---|---|---|
TAbiType |
ABI type to convert to TypeScript representation. | AbiType |
TAbiParameterKind |
Kind to narrow by parameter type. | AbiParameterKind (optional) |
returns | TypeScript primitive type. | TType (inferred) |
Note
Does not include full array or tuple conversion. Use
AbiParameterToPrimitiveType
to fully convert array and tuple types.
import { AbiTypeToPrimitiveType } from 'abitype'
type Result = AbiTypeToPrimitiveType<'address'>
Extracts AbiError
with name from Abi
.
Name | Description | Type |
---|---|---|
TAbi |
ABI. | Abi |
TErrorName |
Name of error. | string (inferred) |
returns | ABI Error. | AbiError |
import { ExtractAbiError } from 'abitype'
const abi = [
{ name: 'ApprovalCallerNotOwnerNorApproved', type: 'error', inputs: [] },
{ name: 'ApprovalQueryForNonexistentToken', type: 'error', inputs: [] },
] as const
type Result = ExtractAbiError<typeof abi, 'ApprovalQueryForNonexistentToken'>
Extracts all AbiError
names from Abi
.
Name | Description | Type |
---|---|---|
TAbi |
ABI. | Abi |
returns | ABI Error names. | string (inferred) |
import { ExtractAbiErrorNames } from 'abitype'
const abi = [
{ name: 'ApprovalCallerNotOwnerNorApproved', type: 'error', inputs: [] },
{ name: 'ApprovalQueryForNonexistentToken', type: 'error', inputs: [] },
] as const
type Result = ExtractAbiErrorNames<typeof abi>
Extracts all AbiError
types from Abi
.
Name | Description | Type |
---|---|---|
TAbi |
ABI. | Abi |
returns | ABI Errors. | AbiError (union) |
import { ExtractAbiErrors } from 'abitype'
const abi = [
{ name: 'ApprovalCallerNotOwnerNorApproved', type: 'error', inputs: [] },
{ name: 'ApprovalQueryForNonexistentToken', type: 'error', inputs: [] },
] as const
type Result = ExtractAbiErrors<typeof abi>
Extracts AbiEvent
with name from Abi
.
Name | Description | Type |
---|---|---|
TAbi |
ABI. | Abi |
TEventName |
Name of event. | string (inferred) |
returns | ABI Event. | AbiEvent |
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<typeof abi, 'Transfer'>
Extracts all AbiEvent
names from Abi
.
Name | Description | Type |
---|---|---|
TAbi |
ABI. | Abi |
returns | ABI Error names. | string (inferred) |
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<typeof abi>
Extracts all AbiEvent
types from Abi
.
Name | Description | Type |
---|---|---|
TAbi |
ABI. | Abi |
returns | ABI Events. | AbiEvent (union) |
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<typeof abi>
Extracts AbiFunction
with name from Abi
.
Name | Description | Type |
---|---|---|
TAbi |
ABI. | Abi |
TFunctionName |
Name of function. | string (inferred) |
returns | ABI Function. | AbiFunction |
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<typeof abi, 'balanceOf'>
Extracts all AbiFunction
names from Abi
.
Name | Description | Type |
---|---|---|
TAbi |
ABI. | Abi |
TAbiStateMutibility |
ABI state mutability. | AbiStateMutability (optional) |
returns | ABI Event names. | string (inferred) |
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<typeof abi>
Extracts all AbiFunction
types from Abi
.
Name | Description | Type |
---|---|---|
TAbi |
ABI. | Abi |
returns | ABI Functions. | AbiFunction (union) |
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<typeof abi>
By default, extracts all functions, but you can also filter by AbiStateMutability
:
type Result = ExtractAbiFunctions<typeof erc721Abi, 'view'>
Checks if type is Abi
.
Name | Description | Type |
---|---|---|
TAbi |
ABI. | Abi |
returns | Boolean value. true if valid Abi , false if not. |
boolean |
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<typeof abi>
Checks if type is TypedData
.
Name | Description | Type |
---|---|---|
TTypedData |
EIP-712 Typed Data schema. | TypedData |
returns | Boolean value. true if valid TypedData , false if not. |
boolean |
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<typeof types>
Converts EIP-712 TypedData
to corresponding TypeScript primitive type.
Name | Description | Type |
---|---|---|
TTypedData |
EIP-712 Typed Data schema. | TypedData |
returns | TypeScript representation of schema. | { [name: string]: TType } (inferred) |
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<typeof types>
Type matching the Contract ABI Specification
import { Abi } from 'abitype'
ABI Error type
import { AbiError } from 'abitype'
ABI Event type
import { AbiEvent } from 'abitype'
ABI Function type
import { AbiFunction } from 'abitype'
Representation used by Solidity compiler (e.g. 'string'
, 'int256'
, 'struct Foo'
)
import { AbiInternalType } from 'abitype'
inputs
and ouputs
item for ABI functions, events, and errors
import { AbiParameter } from 'abitype'
Kind of ABI parameter: 'inputs' | 'outputs'
import { AbiParameterKind } from 'abitype'
ABI Function behavior
import { AbiStateMutability } from 'abitype'
ABI canonical types
import { AbiType } from 'abitype'
Solidity types as template strings
import {
SolidityAddress,
SolidityArray,
SolidityBool,
SolidityBytes,
SolidityFunction,
SolidityInt,
SolidityString,
SolidityTuple,
} from 'abitype'
EIP-712 Typed Data Specification
import { TypedData } from 'abitype'
EIP-712 Domain
import { TypedDataDomain } from 'abitype'
Entry in TypedData
type items
import { TypedDataParameter } from 'abitype'
Subset of AbiType
that excludes tuple
and function
import { TypedDataType } from 'abitype'
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:
Option | Type | Default | Description |
---|---|---|---|
AddressType |
any |
`0x${string}` |
TypeScript type to use for address values. |
ArrayMaxDepth |
number | false |
false |
Maximum depth for nested array types (e.g. string[][] ). When false , there is no maximum array depth. |
BigIntType |
any |
bigint |
TypeScript type to use for int<M> and uint<M> values, where M > 48 . |
BytesType |
{ inputs: any; outputs: any } |
{ inputs: `0x${string}` | Uint8Array; outputs: `0x${string}` } |
TypeScript type to use for bytes<M> values. |
FixedArrayMinLength |
number |
1 |
Lower bound for fixed-length arrays |
FixedArrayMaxLength |
number |
99 |
Upper bound for fixed-length arrays |
IntType |
any |
number |
TypeScript type to use for int<M> and uint<M> values, where M <= 48 . |
StrictAbiType |
boolean |
false |
When set, validates AbiParameter 's type against AbiType . |
Warning
When configuring
ArrayMaxDepth
,FixedArrayMinLength
, andFixedArrayMaxLength
, there are trade-offs. For example, choosing a non-false value forArrayMaxDepth
and increasing the range betweenFixedArrayMinLength
andFixedArrayMaxLength
will make your types more exhaustive, but will also slow down the compiler for type checking, autocomplete, etc.
Configuration options are customizable using declaration merging. Just install abitype
(make sure versions match) and extend the Config
interface either directly in your code or in a d.ts
file (e.g. abi.d.ts
):
declare module 'abitype' {
export interface Config {
BigIntType: MyCustomBigIntType
}
}
ABIType exports the core types as Zod schemas from the abitype/zod
entrypoint. Install required peer dependency:
npm install zod
pnpm add zod
yarn add zod
Then, import and use schemas:
import { Abi } from 'abitype/zod'
const result = await fetch(
'https://api.etherscan.io/api?module=contract&action=getabi&address=0x…',
)
const abi = Abi.parse(result)
If you find ABIType useful, please consider supporting development. Thank you 🙏
If you're interested in contributing, please read the contributing docs before submitting a pull request.
MIT License