diff options
author | Leonid <logvinov.leon@gmail.com> | 2018-01-19 20:43:32 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-19 20:43:32 +0800 |
commit | e1af25c8a6fa96c665d63fff2033d7611b023db2 (patch) | |
tree | 5769ca73d50c497e46e6c6c927700ae0fa00bec9 /packages/deployer/src/utils/contract.ts | |
parent | 9ccf63b44afe1ae6ccc2b9298ee35697d6be9e30 (diff) | |
parent | 6091f818da7cddcb4a22a573f7726ba9b76b398e (diff) | |
download | dexon-0x-contracts-e1af25c8a6fa96c665d63fff2033d7611b023db2.tar.gz dexon-0x-contracts-e1af25c8a6fa96c665d63fff2033d7611b023db2.tar.zst dexon-0x-contracts-e1af25c8a6fa96c665d63fff2033d7611b023db2.zip |
Merge pull request #323 from 0xProject/feature/separate-deployer
Move deployer to a separate package
Diffstat (limited to 'packages/deployer/src/utils/contract.ts')
-rw-r--r-- | packages/deployer/src/utils/contract.ts | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/packages/deployer/src/utils/contract.ts b/packages/deployer/src/utils/contract.ts new file mode 100644 index 000000000..546e82dfb --- /dev/null +++ b/packages/deployer/src/utils/contract.ts @@ -0,0 +1,81 @@ +import { schemas, SchemaValidator } from '@0xproject/json-schemas'; +import { promisify } from '@0xproject/utils'; +import * as _ from 'lodash'; +import * as Web3 from 'web3'; + +import { AbiType } from './types'; + +export class Contract implements Web3.ContractInstance { + public address: string; + public abi: Web3.ContractAbi; + private _contract: Web3.ContractInstance; + private _defaults: Partial<Web3.TxData>; + private _validator: SchemaValidator; + // This class instance is going to be populated with functions and events depending on the ABI + // and we don't know their types in advance + [name: string]: any; + constructor(web3ContractInstance: Web3.ContractInstance, defaults: Partial<Web3.TxData>) { + this._contract = web3ContractInstance; + this.address = web3ContractInstance.address; + this.abi = web3ContractInstance.abi; + this._defaults = defaults; + this._populateEvents(); + this._populateFunctions(); + this._validator = new SchemaValidator(); + } + private _populateFunctions(): void { + const functionsAbi = _.filter(this.abi, abiPart => abiPart.type === AbiType.Function) as Web3.FunctionAbi[]; + _.forEach(functionsAbi, (functionAbi: Web3.MethodAbi) => { + if (functionAbi.constant) { + const cbStyleCallFunction = this._contract[functionAbi.name].call; + this[functionAbi.name] = { + callAsync: promisify(cbStyleCallFunction, this._contract), + }; + } else { + const cbStyleFunction = this._contract[functionAbi.name]; + const cbStyleEstimateGasFunction = this._contract[functionAbi.name].estimateGas; + this[functionAbi.name] = { + estimateGasAsync: promisify(cbStyleEstimateGasFunction, this._contract), + sendTransactionAsync: this._promisifyWithDefaultParams(cbStyleFunction), + }; + } + }); + } + private _populateEvents(): void { + const eventsAbi = _.filter(this.abi, abiPart => abiPart.type === AbiType.Event) as Web3.EventAbi[]; + _.forEach(eventsAbi, (eventAbi: Web3.EventAbi) => { + this[eventAbi.name] = this._contract[eventAbi.name]; + }); + } + private _promisifyWithDefaultParams(fn: (...args: any[]) => void): (...args: any[]) => Promise<any> { + const promisifiedWithDefaultParams = async (...args: any[]) => { + const promise = new Promise((resolve, reject) => { + const lastArg = args[args.length - 1]; + let txData: Partial<Web3.TxData> = {}; + if (this._isTxData(lastArg)) { + txData = args.pop(); + } + txData = { + ...this._defaults, + ...txData, + }; + const callback = (err: Error, data: any) => { + if (_.isNull(err)) { + resolve(data); + } else { + reject(err); + } + }; + args.push(txData); + args.push(callback); + fn.apply(this._contract, args); + }); + return promise; + }; + return promisifiedWithDefaultParams; + } + private _isTxData(lastArg: any): boolean { + const isValid = this._validator.isValid(lastArg, schemas.txDataSchema); + return isValid; + } +} |