Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
The abitype npm package is designed to provide TypeScript types for Ethereum ABI (Application Binary Interface) definitions. It helps developers to work with Ethereum smart contracts in a type-safe manner, ensuring that the interactions with the contracts are correctly typed and reducing the risk of runtime errors.
Define ABI Types
This feature allows you to define the ABI of a smart contract in a type-safe manner. The `Abi` type ensures that the structure of the ABI is correct and helps catch errors at compile time.
import { Abi } from 'abitype';
const myAbi: Abi = [
{
"constant": true,
"inputs": [],
"name": "myFunction",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
];
Type-safe Contract Interactions
This feature allows you to interact with smart contract functions in a type-safe manner. By defining the ABI and using the `AbiFunction` type, you can ensure that the interactions with the contract are correctly typed.
import { Abi, AbiFunction } from 'abitype';
const myAbi: Abi = [
{
"constant": true,
"inputs": [],
"name": "myFunction",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
];
const myFunction: AbiFunction = myAbi[0];
// Now you can interact with the function in a type-safe way
const result: number = await myContract.methods.myFunction().call();
The ethers.js library is a complete and compact library for interacting with the Ethereum blockchain. It provides utilities for working with Ethereum smart contracts, including ABI encoding/decoding, but it is more comprehensive and includes features for managing wallets, interacting with the blockchain, and more. Compared to abitype, ethers.js is a more feature-rich library but may be overkill if you only need type-safe ABI definitions.
The web3.js library is another comprehensive library for interacting with the Ethereum blockchain. It provides similar functionalities to ethers.js, including ABI encoding/decoding, contract interactions, and more. Like ethers.js, it is more feature-rich compared to abitype and is suitable for developers who need a full suite of tools for Ethereum development.
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 (see examples). No need to generate types with third-party tools – just use your ABI and let TypeScript do the rest!
npm install abitype
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([...])
Converts AbiParameter
to corresponding TypeScript primitive type.
import { AbiParameterToPrimitiveType } from 'abitype'
type Result = AbiParameterToPrimitiveType<{
name: 'owner'
type: 'address'
}>
Converts array of AbiParameter
to corresponding TypeScript primitive types.
import { AbiParametersToPrimitiveTypes } from 'abitype'
type Result = AbiParametersToPrimitiveTypes<
[
{
name: 'to'
type: 'address'
},
{
name: 'tokenId'
type: 'uint256'
},
]
>
Converts AbiType
to corresponding TypeScript primitive type.
import { AbiParametersToPrimitiveTypes } from 'abitype'
type Result = AbiTypeToPrimitiveType<'address'>
Note Does not include full array or tuple conversion. Use
AbiParameterToPrimitiveType
to fully convert array and tuple types.
Extracts all AbiError
types from Abi
import { ExtractAbiError } from 'abitype'
type Result = ExtractAbiError<typeof erc721Abi, 'SomeError'>
Extracts all AbiError
names from Abi
import { ExtractAbiErrorNames } from 'abitype'
type Result = ExtractAbiErrorNames<typeof erc721Abi>
Extracts all AbiError
types from Abi
import { ExtractAbiErrors } from 'abitype'
type Result = ExtractAbiErrors<typeof erc721Abi>
Extracts AbiEvent
with name from Abi
import { ExtractAbiEvent } from 'abitype'
type Result = ExtractAbiEvent<typeof erc721Abi, 'Transfer'>
Extracts all AbiEvent
names from Abi
import { ExtractAbiEventNames } from 'abitype'
type Result = ExtractAbiEventNames<typeof erc721Abi>
Extracts all AbiEvent
types from Abi
import { ExtractAbiEvents } from 'abitype'
type Result = ExtractAbiEvents<typeof erc721Abi>
Extracts AbiFunction
with name from Abi
import { AbiFunction } from 'abitype'
type Result = ExtractAbiFunction<typeof erc721Abi, 'balanceOf'>
Extracts all AbiFunction
names from Abi
import { ExtractAbiFunctionNames } from 'abitype'
type Result = ExtractAbiFunctionNames<typeof erc721Abi>
Extracts all AbiFunction
types from Abi
import { ExtractAbiFunctions } from 'abitype'
type Result = ExtractAbiFunctions<typeof erc721Abi>
By default, extracts all functions, but you can also filter by AbiStateMutability
:
type Result = ExtractAbiFunctions<typeof erc721Abi, 'view'>
Checks if type is Abi
import { IsAbi } from 'abitype'
type Result = IsAbi<typeof erc721Abi>
Checks if type is TypedData
import { IsTypedData } from 'abitype'
type Result = IsTypedData<{
Person: [
{ name: 'name'; type: 'string' },
{ name: 'wallet'; type: 'address' },
]
Mail: [
{ name: 'from'; type: 'Person' },
{ name: 'to'; type: 'Person' },
{ name: 'contents'; type: 'string' },
]
}>
Converts EIP-712 TypedData
to corresponding TypeScript primitive type.
import { TypedDataToPrimitiveTypes } from 'abitype'
type Result = TypedDataToPrimitiveTypes<{
Person: [
{ name: 'name'; type: 'string' },
{ name: 'wallet'; type: 'address' },
]
Mail: [
{ name: 'from'; type: 'Person' },
{ name: 'to'; type: 'Person' },
{ name: 'contents'; type: 'string' },
]
}>
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'
Type of ABI parameter: 'inputs' | 'outputs'
import { AbiParameterType } 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 | any | `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 . |
Configuration options are customizable using declaration merging. Just 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
}
}
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.
ABIType exports the core types as Zod schemas from the abitype/zod
entrypoint. Install required peer dependency:
npm install zod
Then, import and use schemas:
import { Abi } from 'abitype/zod'
const abi = await fetch(
'https://api.etherscan.io/api?module=contract&action=getabi&address=0x…',
)
const parsedAbi = Abi.parse(abi)
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
FAQs
Strict TypeScript types for Ethereum ABIs
The npm package abitype receives a total of 780,213 weekly downloads. As such, abitype popularity was classified as popular.
We found that abitype demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.