diff options
Diffstat (limited to 'packages/utils')
-rw-r--r-- | packages/utils/CHANGELOG.json | 18 | ||||
-rw-r--r-- | packages/utils/CHANGELOG.md | 4 | ||||
-rw-r--r-- | packages/utils/package.json | 10 | ||||
-rw-r--r-- | packages/utils/src/abi_utils.ts | 71 | ||||
-rw-r--r-- | packages/utils/src/constants.ts | 1 | ||||
-rw-r--r-- | packages/utils/src/index.ts | 2 |
6 files changed, 101 insertions, 5 deletions
diff --git a/packages/utils/CHANGELOG.json b/packages/utils/CHANGELOG.json index 0c71963c3..dada0eab3 100644 --- a/packages/utils/CHANGELOG.json +++ b/packages/utils/CHANGELOG.json @@ -1,5 +1,23 @@ [ { + "version": "0.5.2", + "changes": [ + { + "note": "Export NULL_BYTES constant", + "pr": 500 + } + ] + }, + { + "timestamp": 1523462196, + "version": "0.5.1", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { "version": "0.5.0", "changes": [ { diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 018f19a15..2123d1097 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v0.5.1 - _April 11, 2018_ + + * Dependencies updated + ## v0.5.0 - _April 2, 2018_ * Make `AbiDecoder.addABI` public (#485) diff --git a/packages/utils/package.json b/packages/utils/package.json index 491fed040..f3cbdf14c 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/utils", - "version": "0.5.0", + "version": "0.5.1", "description": "0x TS utils", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -21,8 +21,8 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/utils/README.md", "devDependencies": { - "@0xproject/monorepo-scripts": "^0.1.16", - "@0xproject/tslint-config": "^0.4.14", + "@0xproject/monorepo-scripts": "^0.1.17", + "@0xproject/tslint-config": "^0.4.15", "@types/lodash": "4.14.104", "copyfiles": "^1.2.0", "npm-run-all": "^4.1.2", @@ -31,8 +31,8 @@ "typescript": "2.7.1" }, "dependencies": { - "@0xproject/types": "^0.5.0", - "@0xproject/typescript-typings": "^0.0.3", + "@0xproject/types": "^0.6.0", + "@0xproject/typescript-typings": "^0.1.0", "@types/node": "^8.0.53", "bignumber.js": "~4.1.0", "ethers-contracts": "^2.2.1", diff --git a/packages/utils/src/abi_utils.ts b/packages/utils/src/abi_utils.ts new file mode 100644 index 000000000..c4533d42e --- /dev/null +++ b/packages/utils/src/abi_utils.ts @@ -0,0 +1,71 @@ +import { AbiDefinition, AbiType, ConstructorAbi, ContractAbi, DataItem, MethodAbi } from '@0xproject/types'; +import * as _ from 'lodash'; + +export const abiUtils = { + parseFunctionParam(param: DataItem): string { + if (param.type === 'tuple') { + // Parse out tuple types into {type_1, type_2, ..., type_N} + const tupleComponents = param.components; + const paramString = _.map(tupleComponents, component => this.parseFunctionParam(component)); + const tupleParamString = `{${paramString}}`; + return tupleParamString; + } + return param.type; + }, + getFunctionSignature(methodAbi: MethodAbi): string { + const functionName = methodAbi.name; + const parameterTypeList = _.map(methodAbi.inputs, (param: DataItem) => this.parseFunctionParam(param)); + const functionSignature = `${functionName}(${parameterTypeList})`; + return functionSignature; + }, + /** + * Solidity supports function overloading whereas TypeScript does not. + * See: https://solidity.readthedocs.io/en/v0.4.21/contracts.html?highlight=overload#function-overloading + * In order to support overloaded functions, we suffix overloaded function names with an index. + * This index should be deterministic, regardless of function ordering within the smart contract. To do so, + * we assign indexes based on the alphabetical order of function signatures. + * + * E.g + * ['f(uint)', 'f(uint,byte32)'] + * Should always be renamed to: + * ['f1(uint)', 'f2(uint,byte32)'] + * Regardless of the order in which these these overloaded functions are declared within the contract ABI. + */ + renameOverloadedMethods(inputContractAbi: ContractAbi): ContractAbi { + const contractAbi = _.cloneDeep(inputContractAbi); + const methodAbis = contractAbi.filter((abi: AbiDefinition) => abi.type === AbiType.Function) as MethodAbi[]; + // Sort method Abis into alphabetical order, by function signature + const methodAbisOrdered = _.sortBy(methodAbis, [ + (methodAbi: MethodAbi) => { + const functionSignature = this.getFunctionSignature(methodAbi); + return functionSignature; + }, + ]); + // Group method Abis by name (overloaded methods will be grouped together, in alphabetical order) + const methodAbisByName: { [key: string]: MethodAbi[] } = {}; + _.each(methodAbisOrdered, methodAbi => { + (methodAbisByName[methodAbi.name] || (methodAbisByName[methodAbi.name] = [])).push(methodAbi); + }); + // Rename overloaded methods to overloadedMethodName1, overloadedMethodName2, ... + _.each(methodAbisByName, methodAbisWithSameName => { + _.each(methodAbisWithSameName, (methodAbi, i: number) => { + if (methodAbisWithSameName.length > 1) { + const overloadedMethodId = i + 1; + const sanitizedMethodName = `${methodAbi.name}${overloadedMethodId}`; + const indexOfExistingAbiWithSanitizedMethodNameIfExists = _.findIndex( + methodAbis, + currentMethodAbi => currentMethodAbi.name === sanitizedMethodName, + ); + if (indexOfExistingAbiWithSanitizedMethodNameIfExists >= 0) { + const methodName = methodAbi.name; + throw new Error( + `Failed to rename overloaded method '${methodName}' to '${sanitizedMethodName}'. A method with this name already exists.`, + ); + } + methodAbi.name = sanitizedMethodName; + } + }); + }); + return contractAbi; + }, +}; diff --git a/packages/utils/src/constants.ts b/packages/utils/src/constants.ts new file mode 100644 index 000000000..2894d4747 --- /dev/null +++ b/packages/utils/src/constants.ts @@ -0,0 +1 @@ +export const NULL_BYTES = '0x'; diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index debcce746..709ec93b2 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -5,3 +5,5 @@ export { intervalUtils } from './interval_utils'; export { BigNumber } from './configured_bignumber'; export { AbiDecoder } from './abi_decoder'; export { logUtils } from './log_utils'; +export { abiUtils } from './abi_utils'; +export { NULL_BYTES } from './constants'; |