diff options
Diffstat (limited to 'packages/utils/src/abi_encoder/evm_data_type_factory.ts')
-rw-r--r-- | packages/utils/src/abi_encoder/evm_data_type_factory.ts | 87 |
1 files changed, 71 insertions, 16 deletions
diff --git a/packages/utils/src/abi_encoder/evm_data_type_factory.ts b/packages/utils/src/abi_encoder/evm_data_type_factory.ts index 268649148..8e477f856 100644 --- a/packages/utils/src/abi_encoder/evm_data_type_factory.ts +++ b/packages/utils/src/abi_encoder/evm_data_type_factory.ts @@ -2,7 +2,7 @@ import { DataItem, MethodAbi } from 'ethereum-types'; import * as _ from 'lodash'; -import { generateDataItemsFromSignature } from './utils/signature_parser'; +import { generateDataItemFromSignature } from './utils/signature_parser'; import { DataType } from './abstract_data_types/data_type'; import { DataTypeFactory } from './abstract_data_types/interfaces'; @@ -134,32 +134,87 @@ export class EvmDataTypeFactory implements DataTypeFactory { /** * Convenience function for creating a DataType from different inputs. - * @param input A single or set of DataItem or a DataType signature. - * A signature in the form of '<type>' is interpreted as a `DataItem` - * For example, 'string' is interpreted as {type: 'string'} - * A signature in the form '(<type1>, <type2>, ..., <typen>)' is interpreted as `DataItem[]` - * For eaxmple, '(string, uint256)' is interpreted as [{type: 'string'}, {type: 'uint256'}] + * @param input A single or set of DataItem or a signature for an EVM data type. * @return DataType corresponding to input. */ export function create(input: DataItem | DataItem[] | string): DataType { - // Handle different types of input - const isSignature = typeof input === 'string'; - const isTupleSignature = isSignature && (input as string).startsWith('('); - const shouldParseAsTuple = isTupleSignature || _.isArray(input); - // Create input `dataItem` + const dataItem = consolidateDataItemsIntoSingle(input); + const dataType = EvmDataTypeFactory.getInstance().create(dataItem); + return dataType; +} + +/** + * Convenience function to aggregate a single input or a set of inputs into a single DataItem. + * An array of data items is grouped into a single tuple. + * @param input A single data item; a set of data items; a signature. + * @return A single data item corresponding to input. + */ +function consolidateDataItemsIntoSingle(input: DataItem | DataItem[] | string): DataItem { let dataItem: DataItem; - if (shouldParseAsTuple) { - const dataItems = isSignature ? generateDataItemsFromSignature(input as string) : (input as DataItem[]); + if (_.isArray(input)) { + const dataItems = input as DataItem[]; dataItem = { name: '', type: 'tuple', components: dataItems, }; } else { - dataItem = isSignature ? generateDataItemsFromSignature(input as string)[0] : (input as DataItem); + dataItem = _.isString(input) ? generateDataItemFromSignature(input) : (input as DataItem); } - // Create data type - const dataType = EvmDataTypeFactory.getInstance().create(dataItem); + return dataItem; +} + +/** + * Convenience function for creating a Method encoder from different inputs. + * @param methodName name of method. + * @param input A single data item; a set of data items; a signature; or an array of signatures (optional). + * @param output A single data item; a set of data items; a signature; or an array of signatures (optional). + * @return Method corresponding to input. + */ +export function createMethod( + methodName: string, + input?: DataItem | DataItem[] | string | string[], + output?: DataItem | DataItem[] | string | string[], +): Method { + const methodInput = _.isUndefined(input) ? [] : consolidateDataItemsIntoArray(input); + const methodOutput = _.isUndefined(output) ? [] : consolidateDataItemsIntoArray(output); + const methodAbi: MethodAbi = { + name: methodName, + inputs: methodInput, + outputs: methodOutput, + type: 'function', + // default fields not used by ABI + constant: false, + payable: false, + stateMutability: 'nonpayable', + }; + const dataType = new Method(methodAbi); return dataType; } + +/** + * Convenience function that aggregates a single input or a set of inputs into an array of DataItems. + * @param input A single data item; a set of data items; a signature; or an array of signatures. + * @return Array of data items corresponding to input. + */ +function consolidateDataItemsIntoArray(input: DataItem | DataItem[] | string | string[]): DataItem[] { + let dataItems: DataItem[]; + if (_.isArray(input) && _.isEmpty(input)) { + dataItems = []; + } else if (_.isArray(input) && _.isString(input[0])) { + dataItems = []; + _.each(input as string[], (signature: string) => { + const dataItem = generateDataItemFromSignature(signature); + dataItems.push(dataItem); + }); + } else if (_.isArray(input)) { + dataItems = input as DataItem[]; + } else if (typeof input === 'string') { + const dataItem = generateDataItemFromSignature(input); + dataItems = [dataItem]; + } else { + dataItems = [input as DataItem]; + } + return dataItems; +} /* tslint:enable no-construct */ |