At 0x we care a lot about type-safety and have therefore wanted our interactions with smart contracts to be statically typed. Since all the type information is already included in our Solidity code, all we need is a way to move those type definitions into TypeScript (the language we use to write our smart contract tests as well as numerous developer libraries). For more background on why this is helpful, Bloom wrote a great blog post explaining the enormous benefits of adding type-safety to smart contract interactions with TypeScript code.



We’re not the first to want such a tool. There have been multiple similar packages released recently, most notably Typechain and Soltsice. Go-ethereum also has a tool for generating typed Go, Objective-C and Java packages from contract ABIs. After looking through the existing solutions, we still felt the approaches taken were lacking in flexibility and weren’t suiting our needs, so we decided to create our own package: @0xproject/abi-gen.



Before explaining how abi-gen works, let’s go over the existing solutions and describe each of their approaches. I’ve checked each of the tools against a very simple smart contract:

Go-ethereum has a CLI tool called abigen . It accepts an ABI or Solidity file and generates a typed Go/Java/Objective-C wrapper. We've used it before in other projects and it's great. The problems start to arise when you need to customize the generated code (e.g add custom assertions, logging, gas estimates, transaction defaults, etc...). The template is hardcoded in the go-ethereum monorepo and the only way to change it is to fork go-ethereum.

You can find the Go code generated for the above contract at: https://gist.github.com/anonymous/2deeacf8a583101b7c7bffc34901da9b

It doesn’t have it’s dependencies in a shared runtime and therefore is quite verbose. If you’re generating wrappers for multiple contracts — it’ll blow up your bundle size.

Soltsice is very similar to go-ethereum’s abigen but can generate TypeScript wrappers. It also has hardcoded templates as JS template strings, which we would need to tweak. As the TS ecosystem is so diverse, it's hard to expect that you could write one TS template and have it work for everybody. Customization of templates was a hard-requirement for us.

Here is the code it generated: https://gist.github.com/anonymous/d865de223f954d5ab6311cd0f93ff9c8

It has a dependency on Soltsice and uses a custom Web3 object

It also doesn’t follow our coding conventions and requires us to have artifacts, even though they’re not actually required once the wrapper is generated.

Typechain takes a similar approach to Soltsice. It also has hardcoded templates, only theirs have a different style and feature set. Typechain also has a shared runtime that you need to include in your code for it to work.

Here is the code it generated: https://gist.github.com/anonymous/83bef618463cbb8061eac48f4ebe52f4

It doesn’t allow you to estimate gas or get the transaction data

It currently doesn’t include proper type checking of the web3 argument

In our case, we already had a promisify library and having it duplicated in the Typechain runtime felt inefficient

We decided to take the best of each of these packages and to make one that was much more flexible. Our goal was to make a package that allows anyone to fully customize the templates used to generate the TS code. abi-gen uses handlebars as it’s primary templating language and allows you to write any arbitrary template. This gives you an enormous amount of flexibility about how the generated code will look and what it will be able to do. Custom error handlers, logging, assertions, gas estimates, transaction defaults, user confirmations, you name it! And if you don’t need any of these — just drop them from your template and you’ll have a smaller bundle size.



Here is the same contract generated by the templates we use for 0x.js:

It plugs perfectly into our codebase and reuses all the libraries, utils, types that we already have. It also lints without any errors.

If you want to read more on how to use abi-gen, you can read the docs. Feel free to use our templates as a starting point for your own. We encourage you to be creative and adjust them for your specific use-case.



We’ve done lots of the heavy-lifting for you and included some handy helpers available in the templates, such as converters from Solidity types to TypeScript types.



Ready to get started? The best place to start are the docs.



Happy type-safe development!