diff options
Diffstat (limited to 'packages/deployer/src/utils')
-rw-r--r-- | packages/deployer/src/utils/constants.ts | 3 | ||||
-rw-r--r-- | packages/deployer/src/utils/contract.ts | 81 | ||||
-rw-r--r-- | packages/deployer/src/utils/encoder.ts | 20 | ||||
-rw-r--r-- | packages/deployer/src/utils/fs_wrapper.ts | 11 | ||||
-rw-r--r-- | packages/deployer/src/utils/types.ts | 97 | ||||
-rw-r--r-- | packages/deployer/src/utils/utils.ts | 13 |
6 files changed, 225 insertions, 0 deletions
diff --git a/packages/deployer/src/utils/constants.ts b/packages/deployer/src/utils/constants.ts new file mode 100644 index 000000000..8871a470d --- /dev/null +++ b/packages/deployer/src/utils/constants.ts @@ -0,0 +1,3 @@ +export const constants = { + NULL_BYTES: '0x', +}; 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; + } +} diff --git a/packages/deployer/src/utils/encoder.ts b/packages/deployer/src/utils/encoder.ts new file mode 100644 index 000000000..d5f807774 --- /dev/null +++ b/packages/deployer/src/utils/encoder.ts @@ -0,0 +1,20 @@ +import * as _ from 'lodash'; +import * as Web3 from 'web3'; +import * as web3Abi from 'web3-eth-abi'; + +import { AbiType } from './types'; + +export const encoder = { + encodeConstructorArgsFromAbi(args: any[], abi: Web3.ContractAbi): string { + const constructorTypes: string[] = []; + _.each(abi, (element: Web3.AbiDefinition) => { + if (element.type === AbiType.Constructor) { + _.each(element.inputs, (input: Web3.FunctionParameter) => { + constructorTypes.push(input.type); + }); + } + }); + const encodedParameters = web3Abi.encodeParameters(constructorTypes, args); + return encodedParameters; + }, +}; diff --git a/packages/deployer/src/utils/fs_wrapper.ts b/packages/deployer/src/utils/fs_wrapper.ts new file mode 100644 index 000000000..34c7caa0e --- /dev/null +++ b/packages/deployer/src/utils/fs_wrapper.ts @@ -0,0 +1,11 @@ +import { promisify } from '@0xproject/utils'; +import * as fs from 'fs'; + +export const fsWrapper = { + readdirAsync: promisify<string[]>(fs.readdir), + readFileAsync: promisify<string>(fs.readFile), + writeFileAsync: promisify<undefined>(fs.writeFile), + mkdirAsync: promisify<undefined>(fs.mkdir), + doesPathExistSync: fs.existsSync, + removeFileAsync: promisify<undefined>(fs.unlink), +}; diff --git a/packages/deployer/src/utils/types.ts b/packages/deployer/src/utils/types.ts new file mode 100644 index 000000000..e054b9cc2 --- /dev/null +++ b/packages/deployer/src/utils/types.ts @@ -0,0 +1,97 @@ +import { TxData } from '@0xproject/types'; +import * as Web3 from 'web3'; +import * as yargs from 'yargs'; + +export enum AbiType { + Function = 'function', + Constructor = 'constructor', + Event = 'event', + Fallback = 'fallback', +} + +export interface ContractArtifact { + contract_name: string; + networks: ContractNetworks; +} + +export interface ContractNetworks { + [key: number]: ContractData; +} + +export interface ContractData { + solc_version: string; + optimizer_enabled: number; + keccak256: string; + abi: Web3.ContractAbi; + unlinked_binary: string; + address?: string; + constructor_args?: string; + updated_at: number; +} + +export interface SolcErrors { + [key: string]: boolean; +} + +export interface CliOptions extends yargs.Arguments { + artifactsDir: string; + contractsDir: string; + jsonrpcPort: number; + networkId: number; + shouldOptimize: boolean; + gasPrice: string; + account?: string; + contract?: string; + args?: string; +} + +export interface CompilerOptions { + contractsDir: string; + networkId: number; + optimizerEnabled: number; + artifactsDir: string; +} + +export interface DeployerOptions { + artifactsDir: string; + jsonrpcPort: number; + networkId: number; + defaults: Partial<TxData>; +} + +export interface ContractSources { + [key: string]: string; +} + +export interface ImportContents { + contents: string; +} + +// TODO: Consolidate with 0x.js definitions once types are moved into a separate package. +export enum ZeroExError { + ContractDoesNotExist = 'CONTRACT_DOES_NOT_EXIST', + ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST', + UnhandledError = 'UNHANDLED_ERROR', + UserHasNoAssociatedAddress = 'USER_HAS_NO_ASSOCIATED_ADDRESSES', + InvalidSignature = 'INVALID_SIGNATURE', + ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK', + InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER', + InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER', + InsufficientEthBalanceForDeposit = 'INSUFFICIENT_ETH_BALANCE_FOR_DEPOSIT', + InsufficientWEthBalanceForWithdrawal = 'INSUFFICIENT_WETH_BALANCE_FOR_WITHDRAWAL', + InvalidJump = 'INVALID_JUMP', + OutOfGas = 'OUT_OF_GAS', + NoNetworkId = 'NO_NETWORK_ID', + SubscriptionNotFound = 'SUBSCRIPTION_NOT_FOUND', +} + +export interface Token { + address?: string; + name: string; + symbol: string; + decimals: number; + ipfsHash: string; + swarmHash: string; +} + +export type DoneCallback = (err?: Error) => void; diff --git a/packages/deployer/src/utils/utils.ts b/packages/deployer/src/utils/utils.ts new file mode 100644 index 000000000..4390d8813 --- /dev/null +++ b/packages/deployer/src/utils/utils.ts @@ -0,0 +1,13 @@ +export const utils = { + consoleLog(message: string): void { + /* tslint:disable */ + console.log(message); + /* tslint:enable */ + }, + stringifyWithFormatting(obj: any): string { + const jsonReplacer: null = null; + const numberOfJsonSpaces = 4; + const stringifiedObj = JSON.stringify(obj, jsonReplacer, numberOfJsonSpaces); + return stringifiedObj; + }, +}; |