Remove Lodash as a dependency in BaseContract
This commit is contained in:
parent
be52079182
commit
aa10844d9e
@ -304,13 +304,15 @@ export class {{contractName}}Contract extends BaseContract {
|
||||
this._subscriptionManager = new SubscriptionManager<{{contractName}}EventArgs, {{contractName}}Events>(
|
||||
{{contractName}}Contract.ABI(),
|
||||
this._web3Wrapper,
|
||||
);{{/if~}}
|
||||
);
|
||||
{{/if~}}
|
||||
|
||||
{{contractName}}Contract.ABI().forEach((item, index) => {
|
||||
if (item.type === 'function') {
|
||||
const methodAbi = item as MethodAbi;
|
||||
this._methodABIIndex[methodAbi.name] = index;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,6 @@
|
||||
"ethereumjs-vm": "^4.0.0",
|
||||
"ethers": "~4.0.4",
|
||||
"js-sha3": "^0.7.0",
|
||||
"lodash": "^4.17.11",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@ -29,7 +29,6 @@ import Account from 'ethereumjs-account';
|
||||
import * as util from 'ethereumjs-util';
|
||||
import { default as VM } from 'ethereumjs-vm';
|
||||
import PStateManager from 'ethereumjs-vm/dist/state/promisified';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
export { methodAbiToFunctionSignature } from './utils';
|
||||
|
||||
@ -100,7 +99,7 @@ export class BaseContract {
|
||||
values: any[],
|
||||
formatter: (type: string, value: any) => any,
|
||||
): any {
|
||||
return _.map(values, (value: any, i: number) => formatABIDataItem(abis[i], value, formatter));
|
||||
return values.map((value: any, i: number) => formatABIDataItem(abis[i], value, formatter));
|
||||
}
|
||||
protected static _lowercaseAddress(type: string, value: string): string {
|
||||
return type === 'address' ? value.toLowerCase() : value;
|
||||
@ -109,8 +108,7 @@ export class BaseContract {
|
||||
return BigNumber.isBigNumber(value) ? value.toString() : value;
|
||||
}
|
||||
protected static _lookupConstructorAbi(abi: ContractAbi): ConstructorAbi {
|
||||
const constructorAbiIfExists = _.find(
|
||||
abi,
|
||||
const constructorAbiIfExists = abi.find(
|
||||
(abiDefinition: AbiDefinition) => abiDefinition.type === AbiType.Constructor,
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
) as ConstructorAbi | undefined;
|
||||
@ -180,15 +178,14 @@ export class BaseContract {
|
||||
txData: T,
|
||||
estimateGasAsync?: (txData: T) => Promise<number>,
|
||||
): Promise<TxData> {
|
||||
const removeUndefinedProperties = _.pickBy.bind(_);
|
||||
const txDataWithDefaults = removeUndefinedProperties(txData);
|
||||
const txDataWithDefaults = BaseContract._removeUndefinedProperties<T>(txData);
|
||||
if (txDataWithDefaults.gas === undefined && estimateGasAsync !== undefined) {
|
||||
txDataWithDefaults.gas = await estimateGasAsync(txDataWithDefaults);
|
||||
}
|
||||
if (txDataWithDefaults.from !== undefined) {
|
||||
txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase();
|
||||
}
|
||||
return txDataWithDefaults;
|
||||
return txDataWithDefaults as TxData;
|
||||
}
|
||||
protected static _assertCallParams(callData: Partial<CallData>, defaultBlock?: BlockParam): void {
|
||||
assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [
|
||||
@ -200,6 +197,11 @@ export class BaseContract {
|
||||
assert.isBlockParam('defaultBlock', defaultBlock);
|
||||
}
|
||||
}
|
||||
private static _removeUndefinedProperties<T>(props: any): T {
|
||||
const clonedProps = { ...props };
|
||||
Object.keys(clonedProps).forEach(key => clonedProps[key] === undefined && delete clonedProps[key]);
|
||||
return clonedProps;
|
||||
}
|
||||
protected _promiseWithTransactionHash(
|
||||
txHashPromise: Promise<string>,
|
||||
opts: AwaitTransactionSuccessOpts,
|
||||
@ -224,19 +226,19 @@ export class BaseContract {
|
||||
// 1. Optional param passed in to public method call
|
||||
// 2. Global config passed in at library instantiation
|
||||
// 3. Gas estimate calculation + safety margin
|
||||
const removeUndefinedProperties = _.pickBy.bind(_);
|
||||
// tslint:disable-next-line:no-object-literal-type-assertion
|
||||
const txDataWithDefaults = {
|
||||
to: this.address,
|
||||
...removeUndefinedProperties(this._web3Wrapper.getContractDefaults()),
|
||||
...removeUndefinedProperties(txData),
|
||||
};
|
||||
...this._web3Wrapper.getContractDefaults(),
|
||||
...BaseContract._removeUndefinedProperties(txData),
|
||||
} as T;
|
||||
if (txDataWithDefaults.gas === undefined && estimateGasAsync !== undefined) {
|
||||
txDataWithDefaults.gas = await estimateGasAsync(txDataWithDefaults);
|
||||
}
|
||||
if (txDataWithDefaults.from !== undefined) {
|
||||
txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase();
|
||||
}
|
||||
return txDataWithDefaults;
|
||||
return txDataWithDefaults as TxData;
|
||||
}
|
||||
protected async _evmExecAsync(encodedData: string): Promise<string> {
|
||||
const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex');
|
||||
@ -300,7 +302,7 @@ export class BaseContract {
|
||||
return abiEncoder;
|
||||
}
|
||||
protected _lookupAbi(functionSignature: string): MethodAbi {
|
||||
const methodAbi = _.find(this.abi, (abiDefinition: AbiDefinition) => {
|
||||
const methodAbi = this.abi.find((abiDefinition: AbiDefinition) => {
|
||||
if (abiDefinition.type !== AbiType.Function) {
|
||||
return false;
|
||||
}
|
||||
@ -362,14 +364,16 @@ export class BaseContract {
|
||||
(abiDefinition: AbiDefinition) => abiDefinition.type === AbiType.Function,
|
||||
) as MethodAbi[];
|
||||
this._abiEncoderByFunctionSignature = {};
|
||||
_.each(methodAbis, methodAbi => {
|
||||
methodAbis.forEach(methodAbi => {
|
||||
const abiEncoder = new AbiEncoder.Method(methodAbi);
|
||||
const functionSignature = abiEncoder.getSignature();
|
||||
this._abiEncoderByFunctionSignature[functionSignature] = abiEncoder;
|
||||
this._web3Wrapper.abiDecoder.addABI(abi, contractName);
|
||||
});
|
||||
_.each(logDecodeDependencies, (dependencyAbi, dependencyName) => {
|
||||
this._web3Wrapper.abiDecoder.addABI(dependencyAbi, dependencyName);
|
||||
});
|
||||
if (logDecodeDependencies) {
|
||||
Object.entries(logDecodeDependencies).forEach(([dependencyName, dependencyAbi]) =>
|
||||
this._web3Wrapper.abiDecoder.addABI(dependencyAbi, dependencyName),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import {
|
||||
RawLogEntry,
|
||||
} from 'ethereum-types';
|
||||
import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { EventCallback, IndexedFilterValues } from '@0x/types';
|
||||
|
||||
@ -48,10 +47,8 @@ export class SubscriptionManager<ContractEventArgs, ContractEvents extends strin
|
||||
this._onLogRemovedSubscriptionToken = undefined;
|
||||
}
|
||||
public unsubscribeAll(): void {
|
||||
const filterTokens = _.keys(this._filterCallbacks);
|
||||
_.each(filterTokens, filterToken => {
|
||||
this.unsubscribe(filterToken);
|
||||
});
|
||||
const filterTokens = Object.keys(this._filterCallbacks);
|
||||
filterTokens.forEach(filterToken => this.unsubscribe(filterToken));
|
||||
}
|
||||
public unsubscribe(filterToken: string, err?: Error): void {
|
||||
if (this._filters[filterToken] === undefined) {
|
||||
@ -63,7 +60,7 @@ export class SubscriptionManager<ContractEventArgs, ContractEvents extends strin
|
||||
}
|
||||
delete this._filters[filterToken];
|
||||
delete this._filterCallbacks[filterToken];
|
||||
if (_.isEmpty(this._filters)) {
|
||||
if (Object.keys(this._filters).length === 0) {
|
||||
this._stopBlockAndLogStream();
|
||||
}
|
||||
}
|
||||
@ -94,7 +91,7 @@ export class SubscriptionManager<ContractEventArgs, ContractEvents extends strin
|
||||
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi, blockRange);
|
||||
const logs = await this._web3Wrapper.getLogsAsync(filter);
|
||||
const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this));
|
||||
const logsWithDecodedArguments = logs.map(this._tryToDecodeLogOrNoop.bind(this)) as any[];
|
||||
return logsWithDecodedArguments;
|
||||
}
|
||||
protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
|
||||
@ -111,7 +108,8 @@ export class SubscriptionManager<ContractEventArgs, ContractEvents extends strin
|
||||
): void {
|
||||
const logs: LogEntry[] = rawLogs.map(rawLog => marshaller.unmarshalLog(rawLog));
|
||||
logs.forEach(log => {
|
||||
_.forEach(this._filters, (filter: FilterObject, filterToken: string) => {
|
||||
Object.keys(this._filters).forEach((filterToken: string) => {
|
||||
const filter = this._filters[filterToken];
|
||||
if (filterUtils.matchesFilter(log, filter)) {
|
||||
const decodedLog = this._tryToDecodeLogOrNoop(log) as LogWithDecodedArgs<ArgsType>;
|
||||
const logEvent = {
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { DataItem, MethodAbi } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
// tslint:disable-next-line:completed-docs
|
||||
export function formatABIDataItem(abi: DataItem, value: any, formatter: (type: string, value: any) => any): any {
|
||||
const trailingArrayRegex = /\[\d*\]$/;
|
||||
if (abi.type.match(trailingArrayRegex)) {
|
||||
const arrayItemType = abi.type.replace(trailingArrayRegex, '');
|
||||
return _.map(value, val => {
|
||||
return value.map((val: any) => {
|
||||
const arrayItemAbi = {
|
||||
...abi,
|
||||
type: arrayItemType,
|
||||
@ -15,9 +14,15 @@ export function formatABIDataItem(abi: DataItem, value: any, formatter: (type: s
|
||||
});
|
||||
} else if (abi.type === 'tuple') {
|
||||
const formattedTuple: { [componentName: string]: DataItem } = {};
|
||||
_.forEach(abi.components, componentABI => {
|
||||
formattedTuple[componentABI.name] = formatABIDataItem(componentABI, value[componentABI.name], formatter);
|
||||
});
|
||||
if (abi.components) {
|
||||
abi.components.forEach(componentABI => {
|
||||
formattedTuple[componentABI.name] = formatABIDataItem(
|
||||
componentABI,
|
||||
value[componentABI.name],
|
||||
formatter,
|
||||
);
|
||||
});
|
||||
}
|
||||
return formattedTuple;
|
||||
} else {
|
||||
return formatter(abi.type, value);
|
||||
|
@ -3,7 +3,6 @@ import { BigNumber } from '@0x/utils';
|
||||
import { BlockRange, ContractAbi, EventAbi, FilterObject, LogEntry } from 'ethereum-types';
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
import * as jsSHA3 from 'js-sha3';
|
||||
import * as _ from 'lodash';
|
||||
import * as uuid from 'uuid/v4';
|
||||
|
||||
const TOPIC_LENGTH = 32;
|
||||
@ -19,7 +18,8 @@ export const filterUtils = {
|
||||
abi: ContractAbi,
|
||||
blockRange?: BlockRange,
|
||||
): FilterObject {
|
||||
const eventAbi = _.find(abi, { name: eventName }) as EventAbi;
|
||||
// tslint:disable:next-line no-unnecessary-type-assertion
|
||||
const eventAbi = abi.find(abiDefinition => (abiDefinition as EventAbi).name === eventName) as EventAbi;
|
||||
const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi);
|
||||
const topicForEventSignature = ethUtil.addHexPrefix(jsSHA3.keccak256(eventSignature));
|
||||
const topicsForIndexedArgs = filterUtils.getTopicsForIndexedArgs(eventAbi, indexFilterValues);
|
||||
@ -37,7 +37,7 @@ export const filterUtils = {
|
||||
return filter;
|
||||
},
|
||||
getEventSignatureFromAbiByName(eventAbi: EventAbi): string {
|
||||
const types = _.map(eventAbi.inputs, 'type');
|
||||
const types = eventAbi.inputs.map(i => i.type);
|
||||
const signature = `${eventAbi.name}(${types.join(',')})`;
|
||||
return signature;
|
||||
},
|
||||
@ -76,15 +76,15 @@ export const filterUtils = {
|
||||
return true;
|
||||
},
|
||||
doesMatchTopics(logTopics: string[], filterTopics: Array<string[] | string | null>): boolean {
|
||||
const matchesTopic = _.zipWith(logTopics, filterTopics, filterUtils.matchesTopic.bind(filterUtils));
|
||||
const doesMatchTopics = _.every(matchesTopic);
|
||||
const matchesTopic = logTopics.map((logTopic, i) => filterUtils.matchesTopic(logTopic, filterTopics[i]));
|
||||
const doesMatchTopics = matchesTopic.every(m => m);
|
||||
return doesMatchTopics;
|
||||
},
|
||||
matchesTopic(logTopic: string, filterTopic: string[] | string | null): boolean {
|
||||
if (_.isArray(filterTopic)) {
|
||||
return _.includes(filterTopic, logTopic);
|
||||
if (Array.isArray(filterTopic)) {
|
||||
return filterTopic.includes(logTopic);
|
||||
}
|
||||
if (_.isString(filterTopic)) {
|
||||
if (typeof filterTopic === 'string') {
|
||||
return filterTopic === logTopic;
|
||||
}
|
||||
// null topic is a wildcard
|
||||
|
Loading…
x
Reference in New Issue
Block a user