diff options
Diffstat (limited to 'packages/abi-gen')
-rw-r--r-- | packages/abi-gen/CHANGELOG.md | 5 | ||||
-rw-r--r-- | packages/abi-gen/README.md | 8 | ||||
-rw-r--r-- | packages/abi-gen/package.json | 6 | ||||
-rw-r--r-- | packages/abi-gen/src/index.ts | 28 | ||||
-rw-r--r-- | packages/abi-gen/src/types.ts | 1 | ||||
-rw-r--r-- | packages/abi-gen/src/utils.ts | 32 |
6 files changed, 54 insertions, 26 deletions
diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md index b4cce6be0..0afd6abd4 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -1,4 +1,7 @@ # CHANGELOG -vx.x.x +v0.x.x - _TBD, 2018_ ------------------------ +* Fixed array typings with union types (#295) +* Add event ABIs to context data passed to templates (#302) +* Add constructor ABIs to context data passed to templates (#304)
\ No newline at end of file diff --git a/packages/abi-gen/README.md b/packages/abi-gen/README.md index 0eaacd86f..ab2315232 100644 --- a/packages/abi-gen/README.md +++ b/packages/abi-gen/README.md @@ -5,9 +5,9 @@ It's heavily inspired by [Geth abigen](https://github.com/ethereum/go-ethereum/w You can write your custom handlebars templates which will allow you to seamlessly integrate the generated code into your existing codebase with existing conventions. For an example of the generated [wrapper files](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/src/contract_wrappers/generated) check out 0x.js. -[Here](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/src/contract_templates) are the templates used to generate those files. +[Here](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates) are the templates used to generate those files. -## Instalation +## Installation `yarn add -g @0xproject/abi-gen` ## Usage ``` @@ -29,8 +29,8 @@ We could've just used `--abiGlob 'src/artifacts/*.json` but we wanted to exclude The abi file should be either a [Truffle](http://truffleframework.com/) contract artifact (a JSON object with an abi key) or a JSON abi array. ## How to write custom templates? -The best way to get started is to copy [0x.js templates](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/src/contract_templates) and start adjusting them for your needs. -We use [handlebars](handlebarsjs.com) template engine under the hood. +The best way to get started is to copy [0x.js templates](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates) and start adjusting them for your needs. +We use [handlebars](http://handlebarsjs.com/) template engine under the hood. You need to have a master template called `contract.mustache`. it will be used to generate each contract wrapper. Although - you don't need and probably shouldn't write all your logic in a single template file. You can write [partial templates](http://handlebarsjs.com/partials.html) and as long as they are within a partials folder - they will be registered and available. ## Which data/context do I get in my templates? For now you don't get much on top of methods abi, some useful helpers and a contract name because it was enough for our use-case, but if you need something else - create a PR. diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json index ee88595b9..fbf3db687 100644 --- a/packages/abi-gen/package.json +++ b/packages/abi-gen/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/abi-gen", - "version": "0.0.3", + "version": "0.0.4", "description": "Generate contract wrappers from ABI and handlebars templates", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -33,7 +33,7 @@ "yargs": "^10.0.3" }, "devDependencies": { - "@0xproject/tslint-config": "^0.3.0", + "@0xproject/tslint-config": "^0.4.0", "@types/glob": "^5.0.33", "@types/handlebars": "^4.0.36", "@types/mkdirp": "^0.5.1", @@ -43,6 +43,6 @@ "shx": "^0.2.2", "tslint": "5.8.0", "typescript": "~2.6.1", - "web3-typescript-typings": "^0.7.2" + "web3-typescript-typings": "^0.9.0" } } diff --git a/packages/abi-gen/src/index.ts b/packages/abi-gen/src/index.ts index 19d289e49..527af32b1 100644 --- a/packages/abi-gen/src/index.ts +++ b/packages/abi-gen/src/index.ts @@ -2,7 +2,7 @@ import chalk from 'chalk'; import * as fs from 'fs'; -import {sync as globSync} from 'glob'; +import { sync as globSync } from 'glob'; import * as Handlebars from 'handlebars'; import * as _ from 'lodash'; import * as mkdirp from 'mkdirp'; @@ -11,10 +11,12 @@ import * as yargs from 'yargs'; import toSnakeCase = require('to-snake-case'); import * as Web3 from 'web3'; -import {ContextData, ParamKind} from './types'; -import {utils} from './utils'; +import { ContextData, ParamKind } from './types'; +import { utils } from './utils'; +const ABI_TYPE_CONSTRUCTOR = 'constructor'; const ABI_TYPE_METHOD = 'function'; +const ABI_TYPE_EVENT = 'event'; const MAIN_TEMPLATE_NAME = 'contract.mustache'; const args = yargs @@ -32,8 +34,7 @@ const args = yargs describe: 'Folder where to put the output files', type: 'string', demand: true, - }) - .argv; + }).argv; function writeOutputFile(name: string, renderedTsCode: string): void { const fileName = toSnakeCase(name); @@ -66,14 +67,20 @@ for (const abiFileName of abiFileNames) { const namedContent = utils.getNamedContent(abiFileName); utils.log(`Processing: ${chalk.bold(namedContent.name)}...`); const parsedContent = JSON.parse(namedContent.content); - const ABI = _.isArray(parsedContent) ? - parsedContent : // ABI file - parsedContent.abi; // Truffle contracts file + const ABI = _.isArray(parsedContent) + ? parsedContent // ABI file + : parsedContent.abi; // Truffle contracts file if (_.isUndefined(ABI)) { utils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`); utils.log(`Please make sure your ABI file is either an array with ABI entries or an object with the abi key`); process.exit(1); } + + let ctor = ABI.find((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_CONSTRUCTOR) as Web3.ConstructorAbi; + if (_.isUndefined(ctor)) { + ctor = utils.getEmptyConstructor(); // The constructor exists, but it's implicit in JSON's ABI definition + } + const methodAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_METHOD) as Web3.MethodAbi[]; const methodsData = _.map(methodAbis, methodAbi => { _.map(methodAbi.inputs, input => { @@ -89,9 +96,14 @@ for (const abiFileName of abiFileNames) { }; return methodData; }); + + const eventAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_EVENT) as Web3.EventAbi[]; + const contextData = { contractName: namedContent.name, + ctor, methods: methodsData, + events: eventAbis, }; const renderedTsCode = template(contextData); writeOutputFile(namedContent.name, renderedTsCode); diff --git a/packages/abi-gen/src/types.ts b/packages/abi-gen/src/types.ts index 1dc039c83..8b158d77a 100644 --- a/packages/abi-gen/src/types.ts +++ b/packages/abi-gen/src/types.ts @@ -12,4 +12,5 @@ export interface Method extends Web3.MethodAbi { export interface ContextData { contractName: string; methods: Method[]; + events: Web3.EventAbi[]; } diff --git a/packages/abi-gen/src/utils.ts b/packages/abi-gen/src/utils.ts index eaf5a30cc..524c54a5e 100644 --- a/packages/abi-gen/src/utils.ts +++ b/packages/abi-gen/src/utils.ts @@ -1,8 +1,9 @@ import * as fs from 'fs'; import * as _ from 'lodash'; import * as path from 'path'; +import * as Web3 from 'web3'; -import {ParamKind} from './types'; +import { ParamKind } from './types'; export const utils = { solTypeToTsType(paramKind: ParamKind, solType: string): string { @@ -10,23 +11,26 @@ export const utils = { if (solType.match(trailingArrayRegex)) { const arrayItemSolType = solType.replace(trailingArrayRegex, ''); const arrayItemTsType = utils.solTypeToTsType(paramKind, arrayItemSolType); - const arrayTsType = `${arrayItemTsType}[]`; + const arrayTsType = `(${arrayItemTsType})[]`; return arrayTsType; } else { const solTypeRegexToTsType = [ - {regex: '^string$', tsType: 'string'}, - {regex: '^address$', tsType: 'string'}, - {regex: '^bool$', tsType: 'boolean'}, - {regex: '^u?int\\d*$', tsType: 'BigNumber'}, - {regex: '^bytes\\d*$', tsType: 'string'}, + { regex: '^string$', tsType: 'string' }, + { regex: '^address$', tsType: 'string' }, + { regex: '^bool$', tsType: 'boolean' }, + { regex: '^u?int\\d*$', tsType: 'BigNumber' }, + { regex: '^bytes\\d*$', tsType: 'string' }, ]; if (paramKind === ParamKind.Input) { // web3 allows to pass those an non-bignumbers and that's nice // but it always returns stuff as BigNumbers - solTypeRegexToTsType.unshift({regex: '^u?int(8|16|32)?$', tsType: 'number|BigNumber'}); + solTypeRegexToTsType.unshift({ + regex: '^u?int(8|16|32)?$', + tsType: 'number|BigNumber', + }); } for (const regexAndTxType of solTypeRegexToTsType) { - const {regex, tsType} = regexAndTxType; + const { regex, tsType } = regexAndTxType; if (solType.match(regex)) { return tsType; } @@ -41,7 +45,7 @@ export const utils = { const name = path.parse(filename).name; return name; }, - getNamedContent(filename: string): {name: string; content: string} { + getNamedContent(filename: string): { name: string; content: string } { const name = utils.getPartialNameFromFileName(filename); try { const content = fs.readFileSync(filename).toString(); @@ -53,4 +57,12 @@ export const utils = { throw new Error(`Failed to read ${filename}: ${err}`); } }, + getEmptyConstructor(): Web3.ConstructorAbi { + return { + type: 'constructor', + stateMutability: 'nonpayable', + payable: false, + inputs: [], + }; + }, }; |