Skip to content
forked from wevm/abitype

Strict TypeScript types for Ethereum ABIs

License

Notifications You must be signed in to change notification settings

unholypanda/abitype

 
 

Repository files navigation

ABIType

npm Downloads per month

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!

Install

npm install abitype
pnpm add abitype
yarn add abitype

ABIType requires typescript@>=4.9.4

Usage

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([...])

TL;DR

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).

Utilities

AbiParameterToPrimitiveType

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)

Example

TypeScript Playground

import { AbiParameterToPrimitiveType } from 'abitype'

type Result = AbiParameterToPrimitiveType<{
  name: 'owner'
  type: 'address'
}>

AbiParametersToPrimitiveTypes

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)

Example

TypeScript Playground

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
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.

Example

TypeScript Playground

import { AbiTypeToPrimitiveType } from 'abitype'

type Result = AbiTypeToPrimitiveType<'address'>

ExtractAbiError

Extracts AbiError with name from Abi.

Name Description Type
TAbi ABI. Abi
TErrorName Name of error. string (inferred)
returns ABI Error. AbiError

Example

TypeScript Playground

import { ExtractAbiError } from 'abitype'

const abi = [
  { name: 'ApprovalCallerNotOwnerNorApproved', type: 'error', inputs: [] },
  { name: 'ApprovalQueryForNonexistentToken', type: 'error', inputs: [] },
] as const

type Result = ExtractAbiError<typeof abi, 'ApprovalQueryForNonexistentToken'>

ExtractAbiErrorNames

Extracts all AbiError names from Abi.

Name Description Type
TAbi ABI. Abi
returns ABI Error names. string (inferred)

Example

TypeScript Playground

import { ExtractAbiErrorNames } from 'abitype'

const abi = [
  { name: 'ApprovalCallerNotOwnerNorApproved', type: 'error', inputs: [] },
  { name: 'ApprovalQueryForNonexistentToken', type: 'error', inputs: [] },
] as const

type Result = ExtractAbiErrorNames<typeof abi>

ExtractAbiErrors

Extracts all AbiError types from Abi.

Name Description Type
TAbi ABI. Abi
returns ABI Errors. AbiError (union)

Example

TypeScript Playground

import { ExtractAbiErrors } from 'abitype'

const abi = [
  { name: 'ApprovalCallerNotOwnerNorApproved', type: 'error', inputs: [] },
  { name: 'ApprovalQueryForNonexistentToken', type: 'error', inputs: [] },
] as const

type Result = ExtractAbiErrors<typeof abi>

ExtractAbiEvent

Extracts AbiEvent with name from Abi.

Name Description Type
TAbi ABI. Abi
TEventName Name of event. string (inferred)
returns ABI Event. AbiEvent

Example

TypeScript Playground

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'>

ExtractAbiEventNames

Extracts all AbiEvent names from Abi.

Name Description Type
TAbi ABI. Abi
returns ABI Error names. string (inferred)

Example

TypeScript Playground

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>

ExtractAbiEvents

Extracts all AbiEvent types from Abi.

Name Description Type
TAbi ABI. Abi
returns ABI Events. AbiEvent (union)

Example

TypeScript Playground

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>

ExtractAbiFunction

Extracts AbiFunction with name from Abi.

Name Description Type
TAbi ABI. Abi
TFunctionName Name of function. string (inferred)
returns ABI Function. AbiFunction

Example

TypeScript Playground

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'>

ExtractAbiFunctionNames

Extracts all AbiFunction names from Abi.

Name Description Type
TAbi ABI. Abi
TAbiStateMutibility ABI state mutability. AbiStateMutability (optional)
returns ABI Event names. string (inferred)

Example

TypeScript Playground

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>

ExtractAbiFunctions

Extracts all AbiFunction types from Abi.

Name Description Type
TAbi ABI. Abi
returns ABI Functions. AbiFunction (union)

Example

TypeScript Playground

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'>

IsAbi

Checks if type is Abi.

Name Description Type
TAbi ABI. Abi
returns Boolean value. true if valid Abi, false if not. boolean

Example

TypeScript Playground

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>

IsTypedData

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

Example

TypeScript Playground

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>

TypedDataToPrimitiveTypes

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)

Example

TypeScript Playground

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>

Types

Abi

Type matching the Contract ABI Specification

import { Abi } from 'abitype'

AbiError

ABI Error type

import { AbiError } from 'abitype'

AbiEvent

ABI Event type

import { AbiEvent } from 'abitype'

AbiFunction

ABI Function type

import { AbiFunction } from 'abitype'

AbiInternalType

Representation used by Solidity compiler (e.g. 'string', 'int256', 'struct Foo')

import { AbiInternalType } from 'abitype'

AbiParameter

inputs and ouputs item for ABI functions, events, and errors

import { AbiParameter } from 'abitype'

AbiParameterKind

Kind of ABI parameter: 'inputs' | 'outputs'

import { AbiParameterKind } from 'abitype'

AbiStateMutability

ABI Function behavior

import { AbiStateMutability } from 'abitype'

AbiType

ABI canonical types

import { AbiType } from 'abitype'

Solidity types

Solidity types as template strings

import {
  SolidityAddress,
  SolidityArray,
  SolidityBool,
  SolidityBytes,
  SolidityFunction,
  SolidityInt,
  SolidityString,
  SolidityTuple,
} from 'abitype'

TypedData

EIP-712 Typed Data Specification

import { TypedData } from 'abitype'

TypedDataDomain

EIP-712 Domain

import { TypedDataDomain } from 'abitype'

TypedDataParameter

Entry in TypedData type items

import { TypedDataParameter } from 'abitype'

TypedDataType

Subset of AbiType that excludes tuple and function

import { TypedDataType } from 'abitype'

Configuration

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, 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.

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
  }
}

TypeScript Playground

Zod

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)

Support

If you find ABIType useful, please consider supporting development. Thank you 🙏

Contributing

If you're interested in contributing, please read the contributing docs before submitting a pull request.

Authors

License

MIT License

About

Strict TypeScript types for Ethereum ABIs

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 100.0%