Merge branch 'development' into removeMigrateStep

* development:
  Fix lint error
  Fix documentation links in some READMEs
  Fix relative link
  Add step to publishing that upload staging doc jsons, deploys staging website, opens every docs page and asks the dev to confirm that each one renders properly before publishing
  Fix web3Wrapper build command
  Add top-level `yarn lerna:stage_docs` to upload docJsons to the staging S3 bucket for all packages with a docs page
  Added a detailed description of `renameOverloadedMethods` (special thanks to @fabioberger). Updated Javascript styles in the Abi-Gen and Utils packages, around support for function overloading.
  Updated deployer to accept a list of contract directories as input. Contract directories are namespaced to a void clashes. Also in this commit is a fix for overloading contract functions.
  Refactor publish script to have it's main execution body be lean and discrete steps

# Conflicts:
#	packages/contracts/package.json
#	packages/deployer/package.json
This commit is contained in:
Fabio Berger 2018-04-11 19:00:30 +09:00
commit 29dc22e208
40 changed files with 816 additions and 168 deletions

View File

@ -19,6 +19,7 @@
"lerna:rebuild": "run-s lerna:clean lerna:build", "lerna:rebuild": "run-s lerna:clean lerna:build",
"lerna:publish": "run-s lerna:install lerna:rebuild script:publish", "lerna:publish": "run-s lerna:install lerna:rebuild script:publish",
"lerna:publish:dry": "run-s lerna:install lerna:rebuild script:publish:dry", "lerna:publish:dry": "run-s lerna:install lerna:rebuild script:publish:dry",
"lerna:stage_docs": "lerna run docs:stage",
"script:publish": "node ./packages/monorepo-scripts/lib/publish.js", "script:publish": "node ./packages/monorepo-scripts/lib/publish.js",
"script:publish:dry": "IS_DRY_RUN=true yarn script:publish" "script:publish:dry": "IS_DRY_RUN=true yarn script:publish"
}, },

View File

@ -2,7 +2,7 @@
A TypeScript/Javascript library for interacting with the 0x protocol. A TypeScript/Javascript library for interacting with the 0x protocol.
### Read the [Documentation](0xproject.com/docs/0xjs). ### Read the [Documentation](https://0xproject.com/docs/0xjs).
## Installation ## Installation

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node #!/usr/bin/env node
import { AbiDefinition, ConstructorAbi, EventAbi, MethodAbi } from '@0xproject/types'; import { AbiDefinition, ConstructorAbi, EventAbi, MethodAbi } from '@0xproject/types';
import { logUtils } from '@0xproject/utils'; import { abiUtils, logUtils } from '@0xproject/utils';
import chalk from 'chalk'; import chalk from 'chalk';
import * as fs from 'fs'; import * as fs from 'fs';
import { sync as globSync } from 'glob'; import { sync as globSync } from 'glob';
@ -12,7 +12,7 @@ import * as yargs from 'yargs';
import toSnakeCase = require('to-snake-case'); import toSnakeCase = require('to-snake-case');
import { ContextData, ContractsBackend, ParamKind } from './types'; import { ContextData, ContractsBackend, Method, ParamKind } from './types';
import { utils } from './utils'; import { utils } from './utils';
const ABI_TYPE_CONSTRUCTOR = 'constructor'; const ABI_TYPE_CONSTRUCTOR = 'constructor';
@ -83,7 +83,6 @@ function writeOutputFile(name: string, renderedTsCode: string): void {
Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input, args.backend)); Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input, args.backend));
Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output, args.backend)); Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output, args.backend));
if (args.partials) { if (args.partials) {
registerPartials(args.partials); registerPartials(args.partials);
} }
@ -126,11 +125,12 @@ for (const abiFileName of abiFileNames) {
} }
const methodAbis = ABI.filter((abi: AbiDefinition) => abi.type === ABI_TYPE_METHOD) as MethodAbi[]; const methodAbis = ABI.filter((abi: AbiDefinition) => abi.type === ABI_TYPE_METHOD) as MethodAbi[];
const methodsData = _.map(methodAbis, methodAbi => { const sanitizedMethodAbis = abiUtils.renameOverloadedMethods(methodAbis) as MethodAbi[];
_.map(methodAbi.inputs, (input, i: number) => { const methodsData = _.map(methodAbis, (methodAbi, methodAbiIndex: number) => {
_.forEach(methodAbi.inputs, (input, inputIndex: number) => {
if (_.isEmpty(input.name)) { if (_.isEmpty(input.name)) {
// Auto-generated getters don't have parameter names // Auto-generated getters don't have parameter names
input.name = `index_${i}`; input.name = `index_${inputIndex}`;
} }
}); });
// This will make templates simpler // This will make templates simpler
@ -138,6 +138,8 @@ for (const abiFileName of abiFileNames) {
...methodAbi, ...methodAbi,
singleReturnValue: methodAbi.outputs.length === 1, singleReturnValue: methodAbi.outputs.length === 1,
hasReturnValue: methodAbi.outputs.length !== 0, hasReturnValue: methodAbi.outputs.length !== 0,
tsName: sanitizedMethodAbis[methodAbiIndex].name,
functionSignature: abiUtils.getFunctionSignature(methodAbi),
}; };
return methodData; return methodData;
}); });

View File

@ -5,13 +5,6 @@ export enum ParamKind {
Output = 'output', Output = 'output',
} }
export enum AbiType {
Function = 'function',
Constructor = 'constructor',
Event = 'event',
Fallback = 'fallback',
}
export enum ContractsBackend { export enum ContractsBackend {
Web3 = 'web3', Web3 = 'web3',
Ethers = 'ethers', Ethers = 'ethers',
@ -20,6 +13,8 @@ export enum ContractsBackend {
export interface Method extends MethodAbi { export interface Method extends MethodAbi {
singleReturnValue: boolean; singleReturnValue: boolean;
hasReturnValue: boolean; hasReturnValue: boolean;
tsName: string;
functionSignature: string;
} }
export interface ContextData { export interface ContextData {

View File

@ -1,9 +1,9 @@
import { ConstructorAbi, DataItem } from '@0xproject/types'; import { AbiType, ConstructorAbi, DataItem } from '@0xproject/types';
import * as fs from 'fs'; import * as fs from 'fs';
import * as _ from 'lodash'; import * as _ from 'lodash';
import * as path from 'path'; import * as path from 'path';
import { AbiType, ContractsBackend, ParamKind } from './types'; import { ContractsBackend, ParamKind } from './types';
export const utils = { export const utils = {
solTypeToTsType(paramKind: ParamKind, backend: ContractsBackend, solType: string, components?: DataItem[]): string { solTypeToTsType(paramKind: ParamKind, backend: ContractsBackend, solType: string, components?: DataItem[]): string {

View File

@ -1,13 +1,26 @@
import { ContractAbi, DataItem, Provider, TxData, TxDataPayable } from '@0xproject/types'; import {
import { BigNumber } from '@0xproject/utils'; AbiDefinition,
AbiType,
ContractAbi,
DataItem,
MethodAbi,
Provider,
TxData,
TxDataPayable,
} from '@0xproject/types';
import { abiUtils, BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as ethersContracts from 'ethers-contracts'; import * as ethersContracts from 'ethers-contracts';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { formatABIDataItem } from './utils'; import { formatABIDataItem } from './utils';
export interface EthersInterfaceByFunctionSignature {
[key: string]: ethersContracts.Interface;
}
export class BaseContract { export class BaseContract {
protected _ethersInterface: ethersContracts.Interface; protected _ethersInterfacesByFunctionSignature: EthersInterfaceByFunctionSignature;
protected _web3Wrapper: Web3Wrapper; protected _web3Wrapper: Web3Wrapper;
public abi: ContractAbi; public abi: ContractAbi;
public address: string; public address: string;
@ -49,10 +62,37 @@ export class BaseContract {
} }
return txDataWithDefaults; return txDataWithDefaults;
} }
protected _lookupEthersInterface(functionSignature: string): ethersContracts.Interface {
const ethersInterface = this._ethersInterfacesByFunctionSignature[functionSignature];
if (_.isUndefined(ethersInterface)) {
throw new Error(`Failed to lookup method with function signature '${functionSignature}'`);
}
return ethersInterface;
}
protected _lookupAbi(functionSignature: string): MethodAbi {
const methodAbi = _.find(this.abi, (abiDefinition: AbiDefinition) => {
if (abiDefinition.type !== AbiType.Function) {
return false;
}
const abiFunctionSignature = abiUtils.getFunctionSignature(abiDefinition);
if (abiFunctionSignature === functionSignature) {
return true;
}
return false;
}) as MethodAbi;
return methodAbi;
}
constructor(abi: ContractAbi, address: string, provider: Provider, defaults?: Partial<TxData>) { constructor(abi: ContractAbi, address: string, provider: Provider, defaults?: Partial<TxData>) {
this._web3Wrapper = new Web3Wrapper(provider, defaults); this._web3Wrapper = new Web3Wrapper(provider, defaults);
this.abi = abi; this.abi = abi;
this.address = address; this.address = address;
this._ethersInterface = new ethersContracts.Interface(abi); const methodAbis = this.abi.filter(
(abiDefinition: AbiDefinition) => abiDefinition.type === AbiType.Function,
) as MethodAbi[];
this._ethersInterfacesByFunctionSignature = {};
_.each(methodAbis, methodAbi => {
const functionSignature = abiUtils.getFunctionSignature(methodAbi);
this._ethersInterfacesByFunctionSignature[functionSignature] = new ethersContracts.Interface([methodAbi]);
});
} }
} }

View File

@ -41,6 +41,6 @@ export class {{contractName}}Contract extends BaseContract {
{{/each}} {{/each}}
constructor(abi: ContractAbi, address: string, provider: Provider, defaults?: Partial<TxData>) { constructor(abi: ContractAbi, address: string, provider: Provider, defaults?: Partial<TxData>) {
super(abi, address, provider, defaults); super(abi, address, provider, defaults);
classUtils.bindAll(this, ['_ethersInterface', 'address', 'abi', '_web3Wrapper']); classUtils.bindAll(this, ['_ethersInterfacesByFunctionSignature', 'address', 'abi', '_web3Wrapper']);
} }
} // tslint:disable:max-file-line-count } // tslint:disable:max-file-line-count

View File

@ -5,9 +5,9 @@ async callAsync(
defaultBlock?: BlockParam, defaultBlock?: BlockParam,
): Promise<{{> return_type outputs=outputs}}> { ): Promise<{{> return_type outputs=outputs}}> {
const self = this as any as {{contractName}}Contract; const self = this as any as {{contractName}}Contract;
const inputAbi = (_.find(self.abi, {name: '{{this.name}}'}) as MethodAbi).inputs; const inputAbi = self._lookupAbi('{{this.functionSignature}}').inputs;
[{{> params inputs=inputs}}] = BaseContract._formatABIDataItemList(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(self)); [{{> params inputs=inputs}}] = BaseContract._formatABIDataItemList(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(self));
const encodedData = self._ethersInterface.functions.{{this.name}}( const encodedData = self._lookupEthersInterface('{{this.functionSignature}}').functions.{{this.name}}(
{{> params inputs=inputs}} {{> params inputs=inputs}}
).data; ).data;
const callDataWithDefaults = await self._applyDefaultsToTxDataAsync( const callDataWithDefaults = await self._applyDefaultsToTxDataAsync(

View File

@ -1,4 +1,4 @@
public {{this.name}} = { public {{this.tsName}} = {
async sendTransactionAsync( async sendTransactionAsync(
{{> typed_params inputs=inputs}} {{> typed_params inputs=inputs}}
{{#this.payable}} {{#this.payable}}
@ -9,17 +9,17 @@ public {{this.name}} = {
{{/this.payable}} {{/this.payable}}
): Promise<string> { ): Promise<string> {
const self = this as any as {{contractName}}Contract; const self = this as any as {{contractName}}Contract;
const inputAbi = (_.find(self.abi, {name: '{{this.name}}'}) as MethodAbi).inputs; const inputAbi = self._lookupAbi('{{this.functionSignature}}').inputs;
[{{> params inputs=inputs}}] = BaseContract._formatABIDataItemList(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(self)); [{{> params inputs=inputs}}] = BaseContract._formatABIDataItemList(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(self));
const encodedData = self._ethersInterface.functions.{{this.name}}( const encodedData = self._lookupEthersInterface('{{this.functionSignature}}').functions.{{this.name}}(
{{> params inputs=inputs}} {{> params inputs=inputs}}
).data ).data;
const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(
{ {
...txData, ...txData,
data: encodedData, data: encodedData,
}, },
self.{{this.name}}.estimateGasAsync.bind( self.{{this.tsName}}.estimateGasAsync.bind(
self, self,
{{> params inputs=inputs}} {{> params inputs=inputs}}
), ),
@ -32,11 +32,11 @@ public {{this.name}} = {
txData: Partial<TxData> = {}, txData: Partial<TxData> = {},
): Promise<number> { ): Promise<number> {
const self = this as any as {{contractName}}Contract; const self = this as any as {{contractName}}Contract;
const inputAbi = (_.find(self.abi, {name: '{{this.name}}'}) as MethodAbi).inputs; const inputAbi = self._lookupAbi('{{this.functionSignature}}').inputs;
[{{> params inputs=inputs}}] = BaseContract._formatABIDataItemList(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); [{{> params inputs=inputs}}] = BaseContract._formatABIDataItemList(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this));
const encodedData = self._ethersInterface.functions.{{this.name}}( const encodedData = self._lookupEthersInterface('{{this.functionSignature}}').functions.{{this.name}}(
{{> params inputs=inputs}} {{> params inputs=inputs}}
).data ).data;
const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(
{ {
...txData, ...txData,
@ -50,11 +50,11 @@ public {{this.name}} = {
{{> typed_params inputs=inputs}} {{> typed_params inputs=inputs}}
): string { ): string {
const self = this as any as {{contractName}}Contract; const self = this as any as {{contractName}}Contract;
const inputAbi = (_.find(self.abi, {name: '{{this.name}}'}) as MethodAbi).inputs; const inputAbi = self._lookupAbi('{{this.functionSignature}}').inputs;
[{{> params inputs=inputs}}] = BaseContract._formatABIDataItemList(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(self)); [{{> params inputs=inputs}}] = BaseContract._formatABIDataItemList(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(self));
const abiEncodedTransactionData = self._ethersInterface.functions.{{this.name}}( const abiEncodedTransactionData = self._lookupEthersInterface('{{this.name}}').functions.{{this.name}}(
{{> params inputs=inputs}} {{> params inputs=inputs}}
).data ).data;
return abiEncodedTransactionData; return abiEncodedTransactionData;
}, },
{{> callAsync}} {{> callAsync}}

View File

@ -16,7 +16,7 @@
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
"run_mocha": "mocha 'lib/test/**/*.js' --timeout 100000 --bail --exit", "run_mocha": "mocha 'lib/test/**/*.js' --timeout 100000 --bail --exit",
"compile:comment": "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846", "compile:comment": "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846",
"compile": "node ../deployer/lib/src/cli.js compile --contracts ${npm_package_config_contracts} --contracts-dir src/contracts --artifacts-dir ../migrations/src/artifacts", "compile": "node ../deployer/lib/src/cli.js compile --contracts ${npm_package_config_contracts} --contract-dirs src/contracts --artifacts-dir ../migrations/src/artifacts",
"clean": "shx rm -rf ./lib", "clean": "shx rm -rf ./lib",
"generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'", "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'",
"lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'", "lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'",

View File

@ -2,7 +2,7 @@
This repository contains a CLI tool that facilitates compiling and deployment of smart contracts. This repository contains a CLI tool that facilitates compiling and deployment of smart contracts.
### Read the [Documentation](0xproject.com/docs/deployer). ### Read the [Documentation](https://0xproject.com/docs/deployer).
## Installation ## Installation

View File

@ -54,6 +54,7 @@
"@types/semver": "^5.5.0", "@types/semver": "^5.5.0",
"@types/yargs": "^11.0.0", "@types/yargs": "^11.0.0",
"chai": "^4.0.1", "chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"copyfiles": "^1.2.0", "copyfiles": "^1.2.0",
"dirty-chai": "^2.0.1", "dirty-chai": "^2.0.1",
"mocha": "^4.0.1", "mocha": "^4.0.1",

View File

@ -11,7 +11,7 @@ import * as yargs from 'yargs';
import { commands } from './commands'; import { commands } from './commands';
import { constants } from './utils/constants'; import { constants } from './utils/constants';
import { consoleReporter } from './utils/error_reporter'; import { consoleReporter } from './utils/error_reporter';
import { CliOptions, CompilerOptions, DeployerOptions } from './utils/types'; import { CliOptions, CompilerOptions, ContractDirectory, DeployerOptions } from './utils/types';
const DEFAULT_OPTIMIZER_ENABLED = false; const DEFAULT_OPTIMIZER_ENABLED = false;
const DEFAULT_CONTRACTS_DIR = path.resolve('src/contracts'); const DEFAULT_CONTRACTS_DIR = path.resolve('src/contracts');
@ -27,7 +27,7 @@ const DEFAULT_CONTRACTS_LIST = '*';
*/ */
async function onCompileCommandAsync(argv: CliOptions): Promise<void> { async function onCompileCommandAsync(argv: CliOptions): Promise<void> {
const opts: CompilerOptions = { const opts: CompilerOptions = {
contractsDir: argv.contractsDir, contractDirs: getContractDirectoriesFromList(argv.contractDirs),
networkId: argv.networkId, networkId: argv.networkId,
optimizerEnabled: argv.shouldOptimize, optimizerEnabled: argv.shouldOptimize,
artifactsDir: argv.artifactsDir, artifactsDir: argv.artifactsDir,
@ -45,7 +45,7 @@ async function onDeployCommandAsync(argv: CliOptions): Promise<void> {
const web3Wrapper = new Web3Wrapper(provider); const web3Wrapper = new Web3Wrapper(provider);
const networkId = await web3Wrapper.getNetworkIdAsync(); const networkId = await web3Wrapper.getNetworkIdAsync();
const compilerOpts: CompilerOptions = { const compilerOpts: CompilerOptions = {
contractsDir: argv.contractsDir, contractDirs: getContractDirectoriesFromList(argv.contractDirs),
networkId, networkId,
optimizerEnabled: argv.shouldOptimize, optimizerEnabled: argv.shouldOptimize,
artifactsDir: argv.artifactsDir, artifactsDir: argv.artifactsDir,
@ -67,6 +67,29 @@ async function onDeployCommandAsync(argv: CliOptions): Promise<void> {
const deployerArgs = deployerArgsString.split(','); const deployerArgs = deployerArgsString.split(',');
await commands.deployAsync(argv.contract as string, deployerArgs, deployerOpts); await commands.deployAsync(argv.contract as string, deployerArgs, deployerOpts);
} }
/**
* Creates a set of contracts to compile.
* @param contractDirectoriesList Comma separated list of contract directories
* @return Set of contract directories
*/
function getContractDirectoriesFromList(contractDirectoriesList: string): Set<ContractDirectory> {
const directories = new Set();
const possiblyNamespacedDirectories = contractDirectoriesList.split(',');
_.forEach(possiblyNamespacedDirectories, namespacedDirectory => {
const directoryComponents = namespacedDirectory.split(':');
if (directoryComponents.length === 1) {
const directory = { namespace: '', path: directoryComponents[0] };
directories.add(directory);
} else if (directoryComponents.length === 2) {
const directory = { namespace: directoryComponents[0], path: directoryComponents[1] };
directories.add(directory);
} else {
throw new Error(`Unable to parse contracts directory: '${namespacedDirectory}'`);
}
});
return directories;
}
/** /**
* Creates a set of contracts to compile. * Creates a set of contracts to compile.
* @param contracts Comma separated list of contracts to compile * @param contracts Comma separated list of contracts to compile
@ -78,8 +101,7 @@ function getContractsSetFromList(contracts: string): Set<string> {
} }
const contractsArray = contracts.split(','); const contractsArray = contracts.split(',');
_.forEach(contractsArray, contractName => { _.forEach(contractsArray, contractName => {
const fileName = `${contractName}${constants.SOLIDITY_FILE_EXTENSION}`; specifiedContracts.add(contractName);
specifiedContracts.add(fileName);
}); });
return specifiedContracts; return specifiedContracts;
} }
@ -104,10 +126,11 @@ function deployCommandBuilder(yargsInstance: any) {
(() => { (() => {
const identityCommandBuilder = _.identity; const identityCommandBuilder = _.identity;
return yargs return yargs
.option('contracts-dir', { .option('contract-dirs', {
type: 'string', type: 'string',
default: DEFAULT_CONTRACTS_DIR, default: DEFAULT_CONTRACTS_DIR,
description: 'path of contracts directory to compile', description:
"comma separated list of contract directories.\nTo avoid filename clashes, directories should be prefixed with a namespace as follows: 'namespace:/path/to/dir'.",
}) })
.option('network-id', { .option('network-id', {
type: 'number', type: 'number',

View File

@ -1,4 +1,4 @@
import { ContractAbi } from '@0xproject/types'; import { AbiType, ContractAbi, MethodAbi } from '@0xproject/types';
import { logUtils, promisify } from '@0xproject/utils'; import { logUtils, promisify } from '@0xproject/utils';
import * as ethUtil from 'ethereumjs-util'; import * as ethUtil from 'ethereumjs-util';
import * as fs from 'fs'; import * as fs from 'fs';
@ -11,6 +11,8 @@ import solc = require('solc');
import { binPaths } from './solc/bin_paths'; import { binPaths } from './solc/bin_paths';
import { import {
constructContractId,
constructUniqueSourceFileId,
createDirIfDoesNotExistAsync, createDirIfDoesNotExistAsync,
findImportIfExist, findImportIfExist,
getContractArtifactIfExistsAsync, getContractArtifactIfExistsAsync,
@ -23,11 +25,14 @@ import { fsWrapper } from './utils/fs_wrapper';
import { import {
CompilerOptions, CompilerOptions,
ContractArtifact, ContractArtifact,
ContractDirectory,
ContractIdToSourceFileId,
ContractNetworkData, ContractNetworkData,
ContractNetworks, ContractNetworks,
ContractSourceData, ContractSourceDataByFileId,
ContractSources, ContractSources,
ContractSpecificSourceData, ContractSpecificSourceData,
FunctionNameToSeenCount,
} from './utils/types'; } from './utils/types';
import { utils } from './utils/utils'; import { utils } from './utils/utils';
@ -39,20 +44,22 @@ const SOLC_BIN_DIR = path.join(__dirname, '..', '..', 'solc_bin');
* to artifact files. * to artifact files.
*/ */
export class Compiler { export class Compiler {
private _contractsDir: string; private _contractDirs: Set<ContractDirectory>;
private _networkId: number; private _networkId: number;
private _optimizerEnabled: boolean; private _optimizerEnabled: boolean;
private _artifactsDir: string; private _artifactsDir: string;
// This get's set in the beggining of `compileAsync` function. It's not called from a constructor, but it's the only public method of that class and could as well be. // This get's set in the beggining of `compileAsync` function. It's not called from a constructor, but it's the only public method of that class and could as well be.
private _contractSources!: ContractSources; private _contractSources!: ContractSources;
private _specifiedContracts: Set<string> = new Set(); private _specifiedContracts: Set<string> = new Set();
private _contractSourceData: ContractSourceData = {}; private _contractSourceDataByFileId: ContractSourceDataByFileId = {};
/** /**
* Recursively retrieves Solidity source code from directory. * Recursively retrieves Solidity source code from directory.
* @param dirPath Directory to search. * @param dirPath Directory to search.
* @return Mapping of contract fileName to contract source. * @param contractBaseDir Base contracts directory of search tree.
* @return Mapping of sourceFilePath to the contract source.
*/ */
private static async _getContractSourcesAsync(dirPath: string): Promise<ContractSources> { private static async _getContractSourcesAsync(dirPath: string, contractBaseDir: string): Promise<ContractSources> {
let dirContents: string[] = []; let dirContents: string[] = [];
try { try {
dirContents = await fsWrapper.readdirAsync(dirPath); dirContents = await fsWrapper.readdirAsync(dirPath);
@ -68,14 +75,18 @@ export class Compiler {
encoding: 'utf8', encoding: 'utf8',
}; };
const source = await fsWrapper.readFileAsync(contentPath, opts); const source = await fsWrapper.readFileAsync(contentPath, opts);
sources[fileName] = source; if (!_.startsWith(contentPath, contractBaseDir)) {
logUtils.log(`Reading ${fileName} source...`); throw new Error(`Expected content path '${contentPath}' to begin with '${contractBaseDir}'`);
}
const sourceFilePath = contentPath.slice(contractBaseDir.length);
sources[sourceFilePath] = source;
logUtils.log(`Reading ${sourceFilePath} source...`);
} catch (err) { } catch (err) {
logUtils.log(`Could not find file at ${contentPath}`); logUtils.log(`Could not find file at ${contentPath}`);
} }
} else { } else {
try { try {
const nestedSources = await Compiler._getContractSourcesAsync(contentPath); const nestedSources = await Compiler._getContractSourcesAsync(contentPath, contractBaseDir);
sources = { sources = {
...sources, ...sources,
...nestedSources, ...nestedSources,
@ -93,7 +104,7 @@ export class Compiler {
* @return An instance of the Compiler class. * @return An instance of the Compiler class.
*/ */
constructor(opts: CompilerOptions) { constructor(opts: CompilerOptions) {
this._contractsDir = opts.contractsDir; this._contractDirs = opts.contractDirs;
this._networkId = opts.networkId; this._networkId = opts.networkId;
this._optimizerEnabled = opts.optimizerEnabled; this._optimizerEnabled = opts.optimizerEnabled;
this._artifactsDir = opts.artifactsDir; this._artifactsDir = opts.artifactsDir;
@ -105,25 +116,49 @@ export class Compiler {
public async compileAsync(): Promise<void> { public async compileAsync(): Promise<void> {
await createDirIfDoesNotExistAsync(this._artifactsDir); await createDirIfDoesNotExistAsync(this._artifactsDir);
await createDirIfDoesNotExistAsync(SOLC_BIN_DIR); await createDirIfDoesNotExistAsync(SOLC_BIN_DIR);
this._contractSources = await Compiler._getContractSourcesAsync(this._contractsDir); this._contractSources = {};
_.forIn(this._contractSources, this._setContractSpecificSourceData.bind(this)); const contractIdToSourceFileId: ContractIdToSourceFileId = {};
const fileNames = this._specifiedContracts.has(ALL_CONTRACTS_IDENTIFIER) const contractDirs = Array.from(this._contractDirs.values());
? _.keys(this._contractSources) for (const contractDir of contractDirs) {
: Array.from(this._specifiedContracts.values()); const sources = await Compiler._getContractSourcesAsync(contractDir.path, contractDir.path);
for (const fileName of fileNames) { _.forIn(sources, (source, sourceFilePath) => {
await this._compileContractAsync(fileName); const sourceFileId = constructUniqueSourceFileId(contractDir.namespace, sourceFilePath);
// Record the file's source and data
if (!_.isUndefined(this._contractSources[sourceFileId])) {
throw new Error(`Found duplicate source files with ID '${sourceFileId}'`);
} }
this._contractSources[sourceFileId] = source;
// Create a mapping between the contract id and its source file id
const contractId = constructContractId(contractDir.namespace, sourceFilePath);
if (!_.isUndefined(contractIdToSourceFileId[contractId])) {
throw new Error(`Found duplicate contract with ID '${contractId}'`);
}
contractIdToSourceFileId[contractId] = sourceFileId;
});
}
_.forIn(this._contractSources, this._setContractSpecificSourceData.bind(this));
const specifiedContractIds = this._specifiedContracts.has(ALL_CONTRACTS_IDENTIFIER)
? _.keys(contractIdToSourceFileId)
: Array.from(this._specifiedContracts.values());
await Promise.all(
_.map(specifiedContractIds, async contractId =>
this._compileContractAsync(contractIdToSourceFileId[contractId]),
),
);
} }
/** /**
* Compiles contract and saves artifact to artifactsDir. * Compiles contract and saves artifact to artifactsDir.
* @param fileName Name of contract with '.sol' extension. * @param sourceFileId Unique ID of the source file.
*/ */
private async _compileContractAsync(fileName: string): Promise<void> { private async _compileContractAsync(sourceFileId: string): Promise<void> {
if (_.isUndefined(this._contractSources)) { if (_.isUndefined(this._contractSources)) {
throw new Error('Contract sources not yet initialized'); throw new Error('Contract sources not yet initialized');
} }
const contractSpecificSourceData = this._contractSourceData[fileName]; if (_.isUndefined(this._contractSourceDataByFileId[sourceFileId])) {
const currentArtifactIfExists = await getContractArtifactIfExistsAsync(this._artifactsDir, fileName); throw new Error(`Contract source for ${sourceFileId} not yet initialized`);
}
const contractSpecificSourceData = this._contractSourceDataByFileId[sourceFileId];
const currentArtifactIfExists = await getContractArtifactIfExistsAsync(this._artifactsDir, sourceFileId);
const sourceHash = `0x${contractSpecificSourceData.sourceHash.toString('hex')}`; const sourceHash = `0x${contractSpecificSourceData.sourceHash.toString('hex')}`;
const sourceTreeHash = `0x${contractSpecificSourceData.sourceTreeHash.toString('hex')}`; const sourceTreeHash = `0x${contractSpecificSourceData.sourceTreeHash.toString('hex')}`;
@ -162,16 +197,17 @@ export class Compiler {
} }
const solcInstance = solc.setupMethods(requireFromString(solcjs, compilerBinFilename)); const solcInstance = solc.setupMethods(requireFromString(solcjs, compilerBinFilename));
logUtils.log(`Compiling ${fileName} with Solidity v${solcVersion}...`); logUtils.log(`Compiling ${sourceFileId} with Solidity v${solcVersion}...`);
const source = this._contractSources[fileName]; const source = this._contractSources[sourceFileId];
const input = { const input = {
[fileName]: source, [sourceFileId]: source,
}; };
const sourcesToCompile = { const sourcesToCompile = {
sources: input, sources: input,
}; };
const compiled = solcInstance.compile(sourcesToCompile, Number(this._optimizerEnabled), importPath => const compiled = solcInstance.compile(sourcesToCompile, Number(this._optimizerEnabled), importPath =>
findImportIfExist(this._contractSources, importPath), findImportIfExist(this._contractSources, sourceFileId, importPath),
); );
if (!_.isUndefined(compiled.errors)) { if (!_.isUndefined(compiled.errors)) {
@ -193,11 +229,11 @@ export class Compiler {
}); });
} }
} }
const contractName = path.basename(fileName, constants.SOLIDITY_FILE_EXTENSION); const contractName = path.basename(sourceFileId, constants.SOLIDITY_FILE_EXTENSION);
const contractIdentifier = `${fileName}:${contractName}`; const contractIdentifier = `${sourceFileId}:${contractName}`;
if (_.isUndefined(compiled.contracts[contractIdentifier])) { if (_.isUndefined(compiled.contracts[contractIdentifier])) {
throw new Error( throw new Error(
`Contract ${contractName} not found in ${fileName}. Please make sure your contract has the same name as it's file name`, `Contract ${contractName} not found in ${sourceFileId}. Please make sure your contract has the same name as it's file name`,
); );
} }
const abi: ContractAbi = JSON.parse(compiled.contracts[contractIdentifier].interface); const abi: ContractAbi = JSON.parse(compiled.contracts[contractIdentifier].interface);
@ -207,6 +243,7 @@ export class Compiler {
const sourceMapRuntime = compiled.contracts[contractIdentifier].srcmapRuntime; const sourceMapRuntime = compiled.contracts[contractIdentifier].srcmapRuntime;
const sources = _.keys(compiled.sources); const sources = _.keys(compiled.sources);
const updated_at = Date.now(); const updated_at = Date.now();
const contractNetworkData: ContractNetworkData = { const contractNetworkData: ContractNetworkData = {
solc_version: solcVersion, solc_version: solcVersion,
keccak256: sourceHash, keccak256: sourceHash,
@ -243,28 +280,30 @@ export class Compiler {
const artifactString = utils.stringifyWithFormatting(newArtifact); const artifactString = utils.stringifyWithFormatting(newArtifact);
const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`; const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`;
await fsWrapper.writeFileAsync(currentArtifactPath, artifactString); await fsWrapper.writeFileAsync(currentArtifactPath, artifactString);
logUtils.log(`${fileName} artifact saved!`); logUtils.log(`${sourceFileId} artifact saved!`);
} }
/** /**
* Gets contract dependendencies and keccak256 hash from source. * Gets contract dependendencies and keccak256 hash from source.
* @param source Source code of contract. * @param source Source code of contract.
* @param fileId FileId of the contract source file.
* @return Object with contract dependencies and keccak256 hash of source. * @return Object with contract dependencies and keccak256 hash of source.
*/ */
private _setContractSpecificSourceData(source: string, fileName: string): void { private _setContractSpecificSourceData(source: string, fileId: string): void {
if (!_.isUndefined(this._contractSourceData[fileName])) { if (!_.isUndefined(this._contractSourceDataByFileId[fileId])) {
return; return;
} }
const sourceHash = ethUtil.sha3(source); const sourceHash = ethUtil.sha3(source);
const solcVersionRange = parseSolidityVersionRange(source); const solcVersionRange = parseSolidityVersionRange(source);
const dependencies = parseDependencies(source); const dependencies = parseDependencies(source, fileId);
const sourceTreeHash = this._getSourceTreeHash(fileName, sourceHash, dependencies); const sourceTreeHash = this._getSourceTreeHash(fileId, sourceHash, dependencies);
this._contractSourceData[fileName] = { this._contractSourceDataByFileId[fileId] = {
dependencies, dependencies,
solcVersionRange, solcVersionRange,
sourceHash, sourceHash,
sourceTreeHash, sourceTreeHash,
}; };
} }
/** /**
* Gets the source tree hash for a file and its dependencies. * Gets the source tree hash for a file and its dependencies.
* @param fileName Name of contract file. * @param fileName Name of contract file.
@ -276,7 +315,7 @@ export class Compiler {
const dependencySourceTreeHashes = _.map(dependencies, dependency => { const dependencySourceTreeHashes = _.map(dependencies, dependency => {
const source = this._contractSources[dependency]; const source = this._contractSources[dependency];
this._setContractSpecificSourceData(source, dependency); this._setContractSpecificSourceData(source, dependency);
const sourceData = this._contractSourceData[dependency]; const sourceData = this._contractSourceDataByFileId[dependency];
return this._getSourceTreeHash(dependency, sourceData.sourceHash, sourceData.dependencies); return this._getSourceTreeHash(dependency, sourceData.sourceHash, sourceData.dependencies);
}); });
const sourceTreeHashesBuffer = Buffer.concat([sourceHash, ...dependencySourceTreeHashes]); const sourceTreeHashesBuffer = Buffer.concat([sourceHash, ...dependencySourceTreeHashes]);

View File

@ -1,3 +1,4 @@
import { AbiType, ContractAbi, MethodAbi } from '@0xproject/types';
import { logUtils } from '@0xproject/utils'; import { logUtils } from '@0xproject/utils';
import * as _ from 'lodash'; import * as _ from 'lodash';
import * as path from 'path'; import * as path from 'path';
@ -5,8 +6,48 @@ import * as solc from 'solc';
import { constants } from './constants'; import { constants } from './constants';
import { fsWrapper } from './fs_wrapper'; import { fsWrapper } from './fs_wrapper';
import { ContractArtifact, ContractSources } from './types'; import { ContractArtifact, ContractSources, FunctionNameToSeenCount } from './types';
/**
* Constructs a system-wide unique identifier for a source file.
* @param directoryNamespace Namespace of the source file's root contract directory.
* @param sourceFilePath Path to a source file, relative to contractBaseDir.
* @return sourceFileId A system-wide unique identifier for the source file.
*/
export function constructUniqueSourceFileId(directoryNamespace: string, sourceFilePath: string): string {
const namespacePrefix = !_.isEmpty(directoryNamespace) ? `/${directoryNamespace}` : '';
const sourceFilePathNoLeadingSlash = sourceFilePath.replace(/^\/+/g, '');
const sourceFileId = `${namespacePrefix}/${sourceFilePathNoLeadingSlash}`;
return sourceFileId;
}
/**
* Constructs a system-wide unique identifier for a dependency file.
* @param dependencyFilePath Path from a sourceFile to a dependency.
* @param contractBaseDir Base contracts directory of search tree.
* @return sourceFileId A system-wide unique identifier for the source file.
*/
export function constructDependencyFileId(dependencyFilePath: string, sourceFilePath: string): string {
if (_.startsWith(dependencyFilePath, '/')) {
// Path of the form /namespace/path/to/dependency.sol
return dependencyFilePath;
} else {
// Dependency is relative to the source file: ./dependency.sol, ../../some/path/dependency.sol, etc.
// Join the two paths to construct a valid source file id: /namespace/path/to/dependency.sol
return path.join(path.dirname(sourceFilePath), dependencyFilePath);
}
}
/**
* Constructs a system-wide unique identifier for a contract.
* @param directoryNamespace Namespace of the source file's root contract directory.
* @param sourceFilePath Path to a source file, relative to contractBaseDir.
* @return sourceFileId A system-wide unique identifier for contract.
*/
export function constructContractId(directoryNamespace: string, sourceFilePath: string): string {
const namespacePrefix = !_.isEmpty(directoryNamespace) ? `${directoryNamespace}:` : '';
const sourceFileName = path.basename(sourceFilePath, constants.SOLIDITY_FILE_EXTENSION);
const contractId = `${namespacePrefix}${sourceFileName}`;
return contractId;
}
/** /**
* Gets contract data on network or returns if an artifact does not exist. * Gets contract data on network or returns if an artifact does not exist.
* @param artifactsDir Path to the artifacts directory. * @param artifactsDir Path to the artifacts directory.
@ -82,9 +123,10 @@ export function getNormalizedErrMsg(errMsg: string): string {
/** /**
* Parses the contract source code and extracts the dendencies * Parses the contract source code and extracts the dendencies
* @param source Contract source code * @param source Contract source code
* @param sourceFilePath File path of the source code.
* @return List of dependendencies * @return List of dependendencies
*/ */
export function parseDependencies(source: string): string[] { export function parseDependencies(source: string, sourceFileId: string): string[] {
// TODO: Use a proper parser // TODO: Use a proper parser
const IMPORT_REGEX = /(import\s)/; const IMPORT_REGEX = /(import\s)/;
const DEPENDENCY_PATH_REGEX = /"([^"]+)"/; // Source: https://github.com/BlockChainCompany/soljitsu/blob/master/lib/shared.js const DEPENDENCY_PATH_REGEX = /"([^"]+)"/; // Source: https://github.com/BlockChainCompany/soljitsu/blob/master/lib/shared.js
@ -95,8 +137,8 @@ export function parseDependencies(source: string): string[] {
const dependencyMatch = line.match(DEPENDENCY_PATH_REGEX); const dependencyMatch = line.match(DEPENDENCY_PATH_REGEX);
if (!_.isNull(dependencyMatch)) { if (!_.isNull(dependencyMatch)) {
const dependencyPath = dependencyMatch[1]; const dependencyPath = dependencyMatch[1];
const basenName = path.basename(dependencyPath); const dependencyId = constructDependencyFileId(dependencyPath, sourceFileId);
dependencies.push(basenName); dependencies.push(dependencyId);
} }
} }
}); });
@ -107,14 +149,19 @@ export function parseDependencies(source: string): string[] {
* Callback to resolve dependencies with `solc.compile`. * Callback to resolve dependencies with `solc.compile`.
* Throws error if contractSources not yet initialized. * Throws error if contractSources not yet initialized.
* @param contractSources Source codes of contracts. * @param contractSources Source codes of contracts.
* @param importPath Path to an imported dependency. * @param sourceFileId ID of the source file.
* @param importPath Path of dependency source file.
* @return Import contents object containing source code of dependency. * @return Import contents object containing source code of dependency.
*/ */
export function findImportIfExist(contractSources: ContractSources, importPath: string): solc.ImportContents { export function findImportIfExist(
const fileName = path.basename(importPath); contractSources: ContractSources,
const source = contractSources[fileName]; sourceFileId: string,
importPath: string,
): solc.ImportContents {
const dependencyFileId = constructDependencyFileId(importPath, sourceFileId);
const source = contractSources[dependencyFileId];
if (_.isUndefined(source)) { if (_.isUndefined(source)) {
throw new Error(`Contract source not found for ${fileName}`); throw new Error(`Contract source not found for ${dependencyFileId}`);
} }
const importContents: solc.ImportContents = { const importContents: solc.ImportContents = {
contents: source, contents: source,

View File

@ -1,11 +1,9 @@
import { schemas, SchemaValidator } from '@0xproject/json-schemas'; import { schemas, SchemaValidator } from '@0xproject/json-schemas';
import { ContractAbi, EventAbi, FunctionAbi, MethodAbi, TxData } from '@0xproject/types'; import { AbiType, ContractAbi, EventAbi, FunctionAbi, MethodAbi, TxData } from '@0xproject/types';
import { promisify } from '@0xproject/utils'; import { promisify } from '@0xproject/utils';
import * as _ from 'lodash'; import * as _ from 'lodash';
import * as Web3 from 'web3'; import * as Web3 from 'web3';
import { AbiType } from './types';
export class Contract implements Web3.ContractInstance { export class Contract implements Web3.ContractInstance {
public address: string; public address: string;
public abi: ContractAbi; public abi: ContractAbi;

View File

@ -1,9 +1,7 @@
import { AbiDefinition, ContractAbi, DataItem } from '@0xproject/types'; import { AbiDefinition, AbiType, ContractAbi, DataItem } from '@0xproject/types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import * as web3Abi from 'web3-eth-abi'; import * as web3Abi from 'web3-eth-abi';
import { AbiType } from './types';
export const encoder = { export const encoder = {
encodeConstructorArgsFromAbi(args: any[], abi: ContractAbi): string { encodeConstructorArgsFromAbi(args: any[], abi: ContractAbi): string {
const constructorTypes: string[] = []; const constructorTypes: string[] = [];

View File

@ -18,6 +18,11 @@ export interface ContractNetworks {
[key: number]: ContractNetworkData; [key: number]: ContractNetworkData;
} }
export interface ContractDirectory {
path: string;
namespace: string;
}
export interface ContractNetworkData { export interface ContractNetworkData {
solc_version: string; solc_version: string;
optimizer_enabled: boolean; optimizer_enabled: boolean;
@ -40,7 +45,7 @@ export interface SolcErrors {
export interface CliOptions extends yargs.Arguments { export interface CliOptions extends yargs.Arguments {
artifactsDir: string; artifactsDir: string;
contractsDir: string; contractDirs: string;
jsonrpcUrl: string; jsonrpcUrl: string;
networkId: number; networkId: number;
shouldOptimize: boolean; shouldOptimize: boolean;
@ -51,7 +56,7 @@ export interface CliOptions extends yargs.Arguments {
} }
export interface CompilerOptions { export interface CompilerOptions {
contractsDir: string; contractDirs: Set<ContractDirectory>;
networkId: number; networkId: number;
optimizerEnabled: boolean; optimizerEnabled: boolean;
artifactsDir: string; artifactsDir: string;
@ -78,7 +83,11 @@ export interface ContractSources {
[key: string]: string; [key: string]: string;
} }
export interface ContractSourceData { export interface ContractIdToSourceFileId {
[key: string]: string;
}
export interface ContractSourceDataByFileId {
[key: string]: ContractSpecificSourceData; [key: string]: ContractSpecificSourceData;
} }
@ -98,4 +107,8 @@ export interface Token {
swarmHash: string; swarmHash: string;
} }
export interface FunctionNameToSeenCount {
[key: string]: number;
}
export type DoneCallback = (err?: Error) => void; export type DoneCallback = (err?: Error) => void;

View File

@ -3,7 +3,13 @@ import 'mocha';
import { Compiler } from '../src/compiler'; import { Compiler } from '../src/compiler';
import { fsWrapper } from '../src/utils/fs_wrapper'; import { fsWrapper } from '../src/utils/fs_wrapper';
import { CompilerOptions, ContractArtifact, ContractNetworkData, DoneCallback } from '../src/utils/types'; import {
CompilerOptions,
ContractArtifact,
ContractDirectory,
ContractNetworkData,
DoneCallback,
} from '../src/utils/types';
import { exchange_binary } from './fixtures/exchange_bin'; import { exchange_binary } from './fixtures/exchange_bin';
import { constants } from './util/constants'; import { constants } from './util/constants';
@ -13,11 +19,15 @@ const expect = chai.expect;
describe('#Compiler', function() { describe('#Compiler', function() {
this.timeout(constants.timeoutMs); this.timeout(constants.timeoutMs);
const artifactsDir = `${__dirname}/fixtures/artifacts`; const artifactsDir = `${__dirname}/fixtures/artifacts`;
const contractsDir = `${__dirname}/fixtures/contracts`; const mainContractDir: ContractDirectory = { path: `${__dirname}/fixtures/contracts/main`, namespace: 'main' };
const baseContractDir: ContractDirectory = { path: `${__dirname}/fixtures/contracts/base`, namespace: 'base' };
const contractDirs: Set<ContractDirectory> = new Set();
contractDirs.add(mainContractDir);
contractDirs.add(baseContractDir);
const exchangeArtifactPath = `${artifactsDir}/Exchange.json`; const exchangeArtifactPath = `${artifactsDir}/Exchange.json`;
const compilerOpts: CompilerOptions = { const compilerOpts: CompilerOptions = {
artifactsDir, artifactsDir,
contractsDir, contractDirs,
networkId: constants.networkId, networkId: constants.networkId,
optimizerEnabled: constants.optimizerEnabled, optimizerEnabled: constants.optimizerEnabled,
specifiedContracts: new Set(constants.specifiedContracts), specifiedContracts: new Set(constants.specifiedContracts),

View File

@ -47,28 +47,34 @@ describe('Compiler utils', () => {
}); });
describe('#parseDependencies', () => { describe('#parseDependencies', () => {
it('correctly parses Exchange dependencies', async () => { it('correctly parses Exchange dependencies', async () => {
const exchangeSource = await fsWrapper.readFileAsync(`${__dirname}/fixtures/contracts/Exchange.sol`, { const exchangeSource = await fsWrapper.readFileAsync(`${__dirname}/fixtures/contracts/main/Exchange.sol`, {
encoding: 'utf8', encoding: 'utf8',
}); });
expect(parseDependencies(exchangeSource)).to.be.deep.equal([ const sourceFileId = '/main/Exchange.sol';
'TokenTransferProxy.sol', expect(parseDependencies(exchangeSource, sourceFileId)).to.be.deep.equal([
'Token.sol', '/main/TokenTransferProxy.sol',
'SafeMath.sol', '/base/Token.sol',
'/base/SafeMath.sol',
]); ]);
}); });
it('correctly parses TokenTransferProxy dependencies', async () => { it('correctly parses TokenTransferProxy dependencies', async () => {
const exchangeSource = await fsWrapper.readFileAsync( const exchangeSource = await fsWrapper.readFileAsync(
`${__dirname}/fixtures/contracts/TokenTransferProxy.sol`, `${__dirname}/fixtures/contracts/main/TokenTransferProxy.sol`,
{ {
encoding: 'utf8', encoding: 'utf8',
}, },
); );
expect(parseDependencies(exchangeSource)).to.be.deep.equal(['Token.sol', 'Ownable.sol']); const sourceFileId = '/main/TokenTransferProxy.sol';
expect(parseDependencies(exchangeSource, sourceFileId)).to.be.deep.equal([
'/base/Token.sol',
'/base/Ownable.sol',
]);
}); });
// TODO: For now that doesn't work. This will work after we switch to a grammar-based parser // TODO: For now that doesn't work. This will work after we switch to a grammar-based parser
it.skip('correctly parses commented out dependencies', async () => { it.skip('correctly parses commented out dependencies', async () => {
const contractWithCommentedOutDependencies = `// import "./TokenTransferProxy.sol";`; const contractWithCommentedOutDependencies = `// import "./TokenTransferProxy.sol";`;
expect(parseDependencies(contractWithCommentedOutDependencies)).to.be.deep.equal([]); const sourceFileId = '/main/TokenTransferProxy.sol';
expect(parseDependencies(contractWithCommentedOutDependencies, sourceFileId)).to.be.deep.equal([]);
}); });
}); });
}); });

View File

@ -4,7 +4,13 @@ import 'mocha';
import { Compiler } from '../src/compiler'; import { Compiler } from '../src/compiler';
import { Deployer } from '../src/deployer'; import { Deployer } from '../src/deployer';
import { fsWrapper } from '../src/utils/fs_wrapper'; import { fsWrapper } from '../src/utils/fs_wrapper';
import { CompilerOptions, ContractArtifact, ContractNetworkData, DoneCallback } from '../src/utils/types'; import {
CompilerOptions,
ContractArtifact,
ContractDirectory,
ContractNetworkData,
DoneCallback,
} from '../src/utils/types';
import { constructor_args, exchange_binary } from './fixtures/exchange_bin'; import { constructor_args, exchange_binary } from './fixtures/exchange_bin';
import { constants } from './util/constants'; import { constants } from './util/constants';
@ -14,11 +20,15 @@ const expect = chai.expect;
describe('#Deployer', () => { describe('#Deployer', () => {
const artifactsDir = `${__dirname}/fixtures/artifacts`; const artifactsDir = `${__dirname}/fixtures/artifacts`;
const contractsDir = `${__dirname}/fixtures/contracts`;
const exchangeArtifactPath = `${artifactsDir}/Exchange.json`; const exchangeArtifactPath = `${artifactsDir}/Exchange.json`;
const mainContractDir: ContractDirectory = { path: `${__dirname}/fixtures/contracts/main`, namespace: '' };
const baseContractDir: ContractDirectory = { path: `${__dirname}/fixtures/contracts/base`, namespace: 'base' };
const contractDirs: Set<ContractDirectory> = new Set();
contractDirs.add(mainContractDir);
contractDirs.add(baseContractDir);
const compilerOpts: CompilerOptions = { const compilerOpts: CompilerOptions = {
artifactsDir, artifactsDir,
contractsDir, contractDirs,
networkId: constants.networkId, networkId: constants.networkId,
optimizerEnabled: constants.optimizerEnabled, optimizerEnabled: constants.optimizerEnabled,
specifiedContracts: new Set(constants.specifiedContracts), specifiedContracts: new Set(constants.specifiedContracts),

View File

@ -1,6 +1,6 @@
/* /*
Copyright 2017 ZeroEx Intl. Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -19,8 +19,8 @@
pragma solidity 0.4.14; pragma solidity 0.4.14;
import "./TokenTransferProxy.sol"; import "./TokenTransferProxy.sol";
import "./base/Token.sol"; import "/base/Token.sol";
import "./base/SafeMath.sol"; import "/base/SafeMath.sol";
/// @title Exchange - Facilitates exchange of ERC20 tokens. /// @title Exchange - Facilitates exchange of ERC20 tokens.
/// @author Amir Bandeali - <amir@0xProject.com>, Will Warren - <will@0xProject.com> /// @author Amir Bandeali - <amir@0xProject.com>, Will Warren - <will@0xProject.com>

View File

@ -1,6 +1,6 @@
/* /*
Copyright 2017 ZeroEx Intl. Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -18,8 +18,8 @@
pragma solidity 0.4.14; pragma solidity 0.4.14;
import "./base/Token.sol"; import "/base/Token.sol";
import "./base/Ownable.sol"; import "/base/Ownable.sol";
/// @title TokenTransferProxy - Transfers tokens on behalf of contracts that have been approved via decentralized governance. /// @title TokenTransferProxy - Transfers tokens on behalf of contracts that have been approved via decentralized governance.
/// @author Amir Bandeali - <amir@0xProject.com>, Will Warren - <will@0xProject.com> /// @author Amir Bandeali - <amir@0xProject.com>, Will Warren - <will@0xProject.com>

View File

@ -2,7 +2,7 @@
Contains 0x-related json schemas Contains 0x-related json schemas
### Read the [Documentation](0xproject.com/docs/json-schemas). ### Read the [Documentation](https://0xproject.com/docs/json-schemas).
## Installation ## Installation

View File

@ -3,10 +3,49 @@
"networks": { "networks": {
"50": { "50": {
"solc_version": "0.4.21", "solc_version": "0.4.21",
"keccak256": "0x2c3aa2e9dbef58abf57cecc148464d0852a83d7f30bbd2066f2a13b8bd3b1dd0", "keccak256": "0x85fb29ea6c21adcf07f754b2ad06482dd6fcd62d31935e36041b4d064c6a038e",
"source_tree_hash": "0x2c3aa2e9dbef58abf57cecc148464d0852a83d7f30bbd2066f2a13b8bd3b1dd0", "source_tree_hash": "0x85fb29ea6c21adcf07f754b2ad06482dd6fcd62d31935e36041b4d064c6a038e",
"optimizer_enabled": false, "optimizer_enabled": false,
"abi": [ "abi": [
{
"constant": false,
"inputs": [
{
"components": [
{
"components": [
{
"name": "to",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"name": "transferData",
"type": "tuple"
},
{
"name": "callback",
"type": "uint32"
}
],
"name": "nestedTransferData",
"type": "tuple"
}
],
"name": "transfer",
"outputs": [
{
"name": "",
"type": "int256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"constant": true, "constant": true,
"inputs": [ "inputs": [
@ -55,6 +94,39 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"constant": false,
"inputs": [
{
"components": [
{
"name": "to",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"name": "transferData",
"type": "tuple"
},
{
"name": "callback",
"type": "uint32"
}
],
"name": "transfer",
"outputs": [
{
"name": "",
"type": "int256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"payable": false, "payable": false,
@ -84,15 +156,14 @@
"type": "event" "type": "event"
} }
], ],
"bytecode": "bytecode": "0x6060604052341561000f57600080fd5b6127106000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610613806100636000396000f300606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063135cfdb11461006757806327e235e31461009d5780632bd14bb9146100d35780632f8086ba14610109575b600080fd5b341561007257600080fd5b6100876004610082903690610446565b61013f565b604051610094919061051c565b60405180910390f35b34156100a857600080fd5b6100bd60046100b890369061041d565b61015a565b6040516100ca9190610537565b60405180910390f35b34156100de57600080fd5b6100f360046100ee90369061046f565b610172565b6040516101009190610501565b60405180910390f35b341561011457600080fd5b6101296004610124903690610498565b6102e2565b604051610136919061051c565b60405180910390f35b6000610153826000015183602001516102e2565b9050919050565b60006020528060005260406000206000915090505481565b600081602001516000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156101c757600090506102dd565b81602001516000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160200151600080846000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84602001516040516102d09190610537565b60405180910390a3600190505b919050565b60006102ed83610172565b508163ffffffff16905092915050565b6000610309823561059f565b905092915050565b60006060828403121561032357600080fd5b61032d6040610552565b9050600061033d8482850161035d565b600083015250604061035184828501610409565b60208301525092915050565b60006040828403121561036f57600080fd5b6103796040610552565b90506000610389848285016102fd565b600083015250602061039d848285016103f5565b60208301525092915050565b6000604082840312156103bb57600080fd5b6103c56040610552565b905060006103d5848285016102fd565b60008301525060206103e9848285016103f5565b60208301525092915050565b600061040182356105bf565b905092915050565b600061041582356105c9565b905092915050565b60006020828403121561042f57600080fd5b600061043d848285016102fd565b91505092915050565b60006060828403121561045857600080fd5b600061046684828501610311565b91505092915050565b60006040828403121561048157600080fd5b600061048f848285016103a9565b91505092915050565b600080606083850312156104ab57600080fd5b60006104b9858286016103a9565b92505060406104ca85828601610409565b9150509250929050565b6104dd8161057f565b82525050565b6104ec8161058b565b82525050565b6104fb81610595565b82525050565b600060208201905061051660008301846104d4565b92915050565b600060208201905061053160008301846104e3565b92915050565b600060208201905061054c60008301846104f2565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561057557600080fd5b8060405250919050565b60008115159050919050565b6000819050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff821690509190505600a265627a7a72305820716a74dd7e2a73c237481496756750895b57977fc4876b1c48aef9b71759bf836c6578706572696d656e74616cf50037",
"0x6060604052341561000f57600080fd5b6127106000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610406806100636000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806327e235e3146100515780632bd14bb914610087575b600080fd5b341561005c57600080fd5b610071600461006c9036906102b9565b6100bd565b60405161007e9190610344565b60405180910390f35b341561009257600080fd5b6100a760046100a29036906102e2565b6100d5565b6040516100b49190610329565b60405180910390f35b60006020528060005260406000206000915090505481565b600081602001516000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561012a5760009050610240565b81602001516000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160200151600080846000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84602001516040516102339190610344565b60405180910390a3600190505b919050565b600061025182356103a2565b905092915050565b60006040828403121561026b57600080fd5b610275604061035f565b9050600061028584828501610245565b6000830152506020610299848285016102a5565b60208301525092915050565b60006102b182356103c2565b905092915050565b6000602082840312156102cb57600080fd5b60006102d984828501610245565b91505092915050565b6000604082840312156102f457600080fd5b600061030284828501610259565b91505092915050565b6103148161038c565b82525050565b61032381610398565b82525050565b600060208201905061033e600083018461030b565b92915050565b6000602082019050610359600083018461031a565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561038257600080fd5b8060405250919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60008190509190505600a265627a7a72305820d15828219194e8ddaa624e10f9c8823c05268d79753b4c60ef401fb4fe5f09dc6c6578706572696d656e74616cf50037", "runtime_bytecode": "0x606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063135cfdb11461006757806327e235e31461009d5780632bd14bb9146100d35780632f8086ba14610109575b600080fd5b341561007257600080fd5b6100876004610082903690610446565b61013f565b604051610094919061051c565b60405180910390f35b34156100a857600080fd5b6100bd60046100b890369061041d565b61015a565b6040516100ca9190610537565b60405180910390f35b34156100de57600080fd5b6100f360046100ee90369061046f565b610172565b6040516101009190610501565b60405180910390f35b341561011457600080fd5b6101296004610124903690610498565b6102e2565b604051610136919061051c565b60405180910390f35b6000610153826000015183602001516102e2565b9050919050565b60006020528060005260406000206000915090505481565b600081602001516000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156101c757600090506102dd565b81602001516000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160200151600080846000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84602001516040516102d09190610537565b60405180910390a3600190505b919050565b60006102ed83610172565b508163ffffffff16905092915050565b6000610309823561059f565b905092915050565b60006060828403121561032357600080fd5b61032d6040610552565b9050600061033d8482850161035d565b600083015250604061035184828501610409565b60208301525092915050565b60006040828403121561036f57600080fd5b6103796040610552565b90506000610389848285016102fd565b600083015250602061039d848285016103f5565b60208301525092915050565b6000604082840312156103bb57600080fd5b6103c56040610552565b905060006103d5848285016102fd565b60008301525060206103e9848285016103f5565b60208301525092915050565b600061040182356105bf565b905092915050565b600061041582356105c9565b905092915050565b60006020828403121561042f57600080fd5b600061043d848285016102fd565b91505092915050565b60006060828403121561045857600080fd5b600061046684828501610311565b91505092915050565b60006040828403121561048157600080fd5b600061048f848285016103a9565b91505092915050565b600080606083850312156104ab57600080fd5b60006104b9858286016103a9565b92505060406104ca85828601610409565b9150509250929050565b6104dd8161057f565b82525050565b6104ec8161058b565b82525050565b6104fb81610595565b82525050565b600060208201905061051660008301846104d4565b92915050565b600060208201905061053160008301846104e3565b92915050565b600060208201905061054c60008301846104f2565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561057557600080fd5b8060405250919050565b60008115159050919050565b6000819050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff821690509190505600a265627a7a72305820716a74dd7e2a73c237481496756750895b57977fc4876b1c48aef9b71759bf836c6578706572696d656e74616cf50037",
"runtime_bytecode": "updated_at": 1522966321930,
"0x60606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806327e235e3146100515780632bd14bb914610087575b600080fd5b341561005c57600080fd5b610071600461006c9036906102b9565b6100bd565b60405161007e9190610344565b60405180910390f35b341561009257600080fd5b6100a760046100a29036906102e2565b6100d5565b6040516100b49190610329565b60405180910390f35b60006020528060005260406000206000915090505481565b600081602001516000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561012a5760009050610240565b81602001516000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160200151600080846000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84602001516040516102339190610344565b60405180910390a3600190505b919050565b600061025182356103a2565b905092915050565b60006040828403121561026b57600080fd5b610275604061035f565b9050600061028584828501610245565b6000830152506020610299848285016102a5565b60208301525092915050565b60006102b182356103c2565b905092915050565b6000602082840312156102cb57600080fd5b60006102d984828501610245565b91505092915050565b6000604082840312156102f457600080fd5b600061030284828501610259565b91505092915050565b6103148161038c565b82525050565b61032381610398565b82525050565b600060208201905061033e600083018461030b565b92915050565b6000602082019050610359600083018461031a565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561038257600080fd5b8060405250919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60008190509190505600a265627a7a72305820d15828219194e8ddaa624e10f9c8823c05268d79753b4c60ef401fb4fe5f09dc6c6578706572696d656e74616cf50037", "source_map": "60:1093:0:-;;;389:72;;;;;;;;449:5;426:8;:20;435:10;426:20;;;;;;;;;;;;;;;:28;;;;60:1093;;;;;;",
"updated_at": 1522318279735, "source_map_runtime": "60:1093:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;978:172;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;467:352;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;825:147;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;978:172;1051:3;1073:70;1082:18;:31;;;1115:18;:27;;;1073:8;:70::i;:::-;1066:77;;978:172;;;:::o;84:41::-;;;;;;;;;;;;;;;;;:::o;467:352::-;528:12;579;:19;;;556:8;:20;565:10;556:20;;;;;;;;;;;;;;;;:42;552:60;;;607:5;600:12;;;;552:60;646:12;:19;;;622:8;:20;631:10;622:20;;;;;;;;;;;;;;;;:43;;;;;;;;;;;704:12;:19;;;675:8;:25;684:12;:15;;;675:25;;;;;;;;;;;;;;;;:48;;;;;;;;;;;754:12;:15;;;733:58;;742:10;733:58;;;771:12;:19;;;733:58;;;;;;;;;;;;;;;808:4;801:11;;467:352;;;;:::o;825:147::-;903:3;918:22;927:12;918:8;:22::i;:::-;;957:8;950:15;;;;825:147;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;;63:55;;57:66;;;;;171:510;;294:4;282:9;277:3;273:19;269:30;266:2;;;312:1;309;302:12;266:2;330:20;345:4;330:20;;;321:29;;408:1;439:73;508:3;499:6;488:9;484:22;439:73;;;433:3;426:5;422:15;415:98;360:164;578:2;611:48;655:3;646:6;635:9;631:22;611:48;;;604:4;597:5;593:16;586:74;534:137;260:421;;;;;723:465;;836:4;824:9;819:3;815:19;811:30;808:2;;;854:1;851;844:12;808:2;872:20;887:4;872:20;;;863:29;;940:1;971:49;1016:3;1007:6;996:9;992:22;971:49;;;965:3;958:5;954:15;947:74;902:130;1084:2;1117:49;1162:3;1153:6;1142:9;1138:22;1117:49;;;1110:4;1103:5;1099:16;1092:75;1042:136;802:386;;;;;1230:469;;1347:4;1335:9;1330:3;1326:19;1322:30;1319:2;;;1365:1;1362;1355:12;1319:2;1383:20;1398:4;1383:20;;;1374:29;;1451:1;1482:49;1527:3;1518:6;1507:9;1503:22;1482:49;;;1476:3;1469:5;1465:15;1458:74;1413:130;1595:2;1628:49;1673:3;1664:6;1653:9;1649:22;1628:49;;;1621:4;1614:5;1610:16;1603:75;1553:136;1313:386;;;;;1706:118;;1773:46;1811:6;1798:20;1773:46;;;1764:55;;1758:66;;;;;1831:116;;1897:45;1934:6;1921:20;1897:45;;;1888:54;;1882:65;;;;;1954:241;;2058:2;2046:9;2037:7;2033:23;2029:32;2026:2;;;2074:1;2071;2064:12;2026:2;2109:1;2126:53;2171:7;2162:6;2151:9;2147:22;2126:53;;;2116:63;;2088:97;2020:175;;;;;2202:309;;2340:2;2328:9;2319:7;2315:23;2311:32;2308:2;;;2356:1;2353;2346:12;2308:2;2391:1;2408:87;2487:7;2478:6;2467:9;2463:22;2408:87;;;2398:97;;2370:131;2302:209;;;;;2518:297;;2650:2;2638:9;2629:7;2625:23;2621:32;2618:2;;;2666:1;2663;2656:12;2618:2;2701:1;2718:81;2791:7;2782:6;2771:9;2767:22;2718:81;;;2708:91;;2680:125;2612:203;;;;;2822:420;;;2970:2;2958:9;2949:7;2945:23;2941:32;2938:2;;;2986:1;2983;2976:12;2938:2;3021:1;3038:81;3111:7;3102:6;3091:9;3087:22;3038:81;;;3028:91;;3000:125;3156:2;3174:52;3218:7;3209:6;3198:9;3194:22;3174:52;;;3164:62;;3135:97;2932:310;;;;;;3249:101;3316:28;3338:5;3316:28;;;3311:3;3304:41;3298:52;;;3357:107;3428:30;3452:5;3428:30;;;3423:3;3416:43;3410:54;;;3471:110;3544:31;3569:5;3544:31;;;3539:3;3532:44;3526:55;;;3588:181;;3690:2;3679:9;3675:18;3667:26;;3704:55;3756:1;3745:9;3741:17;3732:6;3704:55;;;3661:108;;;;;3776:189;;3882:2;3871:9;3867:18;3859:26;;3896:59;3952:1;3941:9;3937:17;3928:6;3896:59;;;3853:112;;;;;3972:193;;4080:2;4069:9;4065:18;4057:26;;4094:61;4152:1;4141:9;4137:17;4128:6;4094:61;;;4051:114;;;;;4172:256;;4234:2;4228:9;4218:19;;4272:4;4264:6;4260:17;4371:6;4359:10;4356:22;4335:18;4323:10;4320:34;4317:62;4314:2;;;4392:1;4389;4382:12;4314:2;4412:10;4408:2;4401:22;4212:216;;;;;4435:92;;4515:5;4508:13;4501:21;4490:32;;4484:43;;;;4534:78;;4602:5;4591:16;;4585:27;;;;4619:79;;4688:5;4677:16;;4671:27;;;;4705:128;;4785:42;4778:5;4774:54;4763:65;;4757:76;;;;4840:79;;4909:5;4898:16;;4892:27;;;;4926:95;;5005:10;4998:5;4994:22;4983:33;;4977:44;;;",
"source_map": "60:662:0:-;;;290:72;;;;;;;;350:5;327:8;:20;336:10;327:20;;;;;;;;;;;;;;;:28;;;;60:662;;;;;;", "sources": [
"source_map_runtime": "/Metacoin.sol"
"60:662:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;368:352;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84:41;;;;;;;;;;;;;;;;;:::o;368:352::-;429:12;480;:19;;;457:8;:20;466:10;457:20;;;;;;;;;;;;;;;;:42;453:60;;;508:5;501:12;;;;453:60;547:12;:19;;;523:8;:20;532:10;523:20;;;;;;;;;;;;;;;;:43;;;;;;;;;;;605:12;:19;;;576:8;:25;585:12;:15;;;576:25;;;;;;;;;;;;;;;;:48;;;;;;;;;;;655:12;:15;;;634:58;;643:10;634:58;;;672:12;:19;;;634:58;;;;;;;;;;;;;;;709:4;702:11;;368:352;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;;63:55;;57:66;;;;;165:469;;282:4;270:9;265:3;261:19;257:30;254:2;;;300:1;297;290:12;254:2;318:20;333:4;318:20;;;309:29;;386:1;417:49;462:3;453:6;442:9;438:22;417:49;;;411:3;404:5;400:15;393:74;348:130;530:2;563:49;608:3;599:6;588:9;584:22;563:49;;;556:4;549:5;545:16;538:75;488:136;248:386;;;;;641:118;;708:46;746:6;733:20;708:46;;;699:55;;693:66;;;;;766:241;;870:2;858:9;849:7;845:23;841:32;838:2;;;886:1;883;876:12;838:2;921:1;938:53;983:7;974:6;963:9;959:22;938:53;;;928:63;;900:97;832:175;;;;;1014:297;;1146:2;1134:9;1125:7;1121:23;1117:32;1114:2;;;1162:1;1159;1152:12;1114:2;1197:1;1214:81;1287:7;1278:6;1267:9;1263:22;1214:81;;;1204:91;;1176:125;1108:203;;;;;1318:101;1385:28;1407:5;1385:28;;;1380:3;1373:41;1367:52;;;1426:110;1499:31;1524:5;1499:31;;;1494:3;1487:44;1481:55;;;1543:181;;1645:2;1634:9;1630:18;1622:26;;1659:55;1711:1;1700:9;1696:17;1687:6;1659:55;;;1616:108;;;;;1731:193;;1839:2;1828:9;1824:18;1816:26;;1853:61;1911:1;1900:9;1896:17;1887:6;1853:61;;;1810:114;;;;;1931:256;;1993:2;1987:9;1977:19;;2031:4;2023:6;2019:17;2130:6;2118:10;2115:22;2094:18;2082:10;2079:34;2076:62;2073:2;;;2151:1;2148;2141:12;2073:2;2171:10;2167:2;2160:22;1971:216;;;;;2194:92;;2274:5;2267:13;2260:21;2249:32;;2243:43;;;;2293:79;;2362:5;2351:16;;2345:27;;;;2379:128;;2459:42;2452:5;2448:54;2437:65;;2431:76;;;;2514:79;;2583:5;2572:16;;2566:27;;;", ]
"sources": ["Metacoin.sol"]
} }
} }
} }

View File

@ -11,6 +11,11 @@ contract Metacoin {
uint256 amount; uint256 amount;
} }
struct NestedTransferData {
TransferData transferData;
uint32 callback;
}
function Metacoin() public { function Metacoin() public {
balances[msg.sender] = 10000; balances[msg.sender] = 10000;
} }
@ -22,4 +27,14 @@ contract Metacoin {
Transfer(msg.sender, transferData.to, transferData.amount); Transfer(msg.sender, transferData.to, transferData.amount);
return true; return true;
} }
function transfer(TransferData transferData, uint32 callback) public returns (int) {
transfer(transferData);
return callback;
}
function transfer(NestedTransferData nestedTransferData) public returns (int) {
return transfer(nestedTransferData.transferData, nestedTransferData.callback);
}
} }

View File

@ -18,7 +18,7 @@
"coverage:report:html": "istanbul report html && open coverage/index.html", "coverage:report:html": "istanbul report html && open coverage/index.html",
"coverage:report:lcov": "istanbul report lcov", "coverage:report:lcov": "istanbul report lcov",
"test:circleci": "yarn test:coverage", "test:circleci": "yarn test:coverage",
"compile": "node ../deployer/lib/src/cli.js compile --contracts Metacoin --contracts-dir contracts --artifacts-dir artifacts" "compile": "node ../deployer/lib/src/cli.js compile --contracts Metacoin --contract-dirs contracts --artifacts-dir artifacts"
}, },
"author": "", "author": "",
"license": "Apache-2.0", "license": "Apache-2.0",

View File

@ -36,12 +36,12 @@ describe('Metacoin', () => {
}); });
}); });
describe('#transfer', () => { describe('#transfer', () => {
it(`should successfully transfer tokens`, async () => { it(`should successfully transfer tokens (via transfer1)`, async () => {
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
const amount = INITIAL_BALANCE.div(2); const amount = INITIAL_BALANCE.div(2);
const oldBalance = await metacoin.balances.callAsync(ZERO_ADDRESS); const oldBalance = await metacoin.balances.callAsync(ZERO_ADDRESS);
expect(oldBalance).to.be.bignumber.equal(0); expect(oldBalance).to.be.bignumber.equal(0);
const txHash = await metacoin.transfer.sendTransactionAsync( const txHash = await metacoin.transfer1.sendTransactionAsync(
{ {
to: ZERO_ADDRESS, to: ZERO_ADDRESS,
amount, amount,
@ -58,5 +58,57 @@ describe('Metacoin', () => {
const newBalance = await metacoin.balances.callAsync(ZERO_ADDRESS); const newBalance = await metacoin.balances.callAsync(ZERO_ADDRESS);
expect(newBalance).to.be.bignumber.equal(amount); expect(newBalance).to.be.bignumber.equal(amount);
}); });
it(`should successfully transfer tokens (via transfer2)`, async () => {
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
const amount = INITIAL_BALANCE.div(2);
const oldBalance = await metacoin.balances.callAsync(ZERO_ADDRESS);
expect(oldBalance).to.be.bignumber.equal(0);
const callback = 59;
const txHash = await metacoin.transfer2.sendTransactionAsync(
{
to: ZERO_ADDRESS,
amount,
},
callback,
{ from: devConstants.TESTRPC_FIRST_ADDRESS },
);
const txReceipt = await web3Wrapper.awaitTransactionMinedAsync(txHash);
const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<TransferContractEventArgs>;
expect(transferLogs.args).to.be.deep.equal({
_to: ZERO_ADDRESS,
_from: devConstants.TESTRPC_FIRST_ADDRESS,
_value: amount,
});
const newBalance = await metacoin.balances.callAsync(ZERO_ADDRESS);
expect(newBalance).to.be.bignumber.equal(amount);
});
it(`should successfully transfer tokens (via transfer3)`, async () => {
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
const amount = INITIAL_BALANCE.div(2);
const oldBalance = await metacoin.balances.callAsync(ZERO_ADDRESS);
expect(oldBalance).to.be.bignumber.equal(0);
const callback = 59;
const txHash = await metacoin.transfer3.sendTransactionAsync(
{
transferData: {
to: ZERO_ADDRESS,
amount,
},
callback,
},
{ from: devConstants.TESTRPC_FIRST_ADDRESS },
);
const txReceipt = await web3Wrapper.awaitTransactionMinedAsync(txHash);
const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<TransferContractEventArgs>;
expect(transferLogs.args).to.be.deep.equal({
_to: ZERO_ADDRESS,
_from: devConstants.TESTRPC_FIRST_ADDRESS,
_value: amount,
});
const newBalance = await metacoin.balances.callAsync(ZERO_ADDRESS);
expect(newBalance).to.be.bignumber.equal(amount);
});
}); });
}); });

View File

@ -29,6 +29,7 @@
"@0xproject/tslint-config": "0.4.13", "@0xproject/tslint-config": "0.4.13",
"@types/glob": "^5.0.33", "@types/glob": "^5.0.33",
"@types/node": "^8.0.53", "@types/node": "^8.0.53",
"@types/opn": "^5.1.0",
"@types/rimraf": "^2.0.2", "@types/rimraf": "^2.0.2",
"depcheck": "^0.6.9", "depcheck": "^0.6.9",
"lerna-get-packages": "^1.0.0", "lerna-get-packages": "^1.0.0",
@ -45,7 +46,9 @@
"glob": "^7.1.2", "glob": "^7.1.2",
"lodash": "^4.17.4", "lodash": "^4.17.4",
"moment": "2.21.0", "moment": "2.21.0",
"opn": "^5.3.0",
"promisify-child-process": "^1.0.5", "promisify-child-process": "^1.0.5",
"prompt": "^1.0.0",
"publish-release": "0xproject/publish-release", "publish-release": "0xproject/publish-release",
"rimraf": "^2.6.2", "rimraf": "^2.6.2",
"semver-diff": "^2.1.0", "semver-diff": "^2.1.0",

View File

@ -2,4 +2,5 @@ import * as path from 'path';
export const constants = { export const constants = {
monorepoRootPath: path.join(__dirname, '../../..'), monorepoRootPath: path.join(__dirname, '../../..'),
stagingWebsite: 'http://staging-0xproject.s3-website-us-east-1.amazonaws.com',
}; };

View File

@ -3,6 +3,11 @@ declare module 'publish-release';
declare module 'es6-promisify'; declare module 'es6-promisify';
declare module 'semver-diff'; declare module 'semver-diff';
declare module 'prompt' {
const start: () => void;
const get: (promptMessages: string[], callback: (err: Error, result: string) => void) => void;
}
// semver-sort declarations // semver-sort declarations
declare module 'semver-sort' { declare module 'semver-sort' {
const desc: (versions: string[]) => string[]; const desc: (versions: string[]) => string[];
@ -15,6 +20,7 @@ declare interface LernaPackage {
version: string; version: string;
name: string; name: string;
main?: string; main?: string;
scripts?: { [command: string]: string };
config?: { config?: {
additionalTsTypings?: string[]; additionalTsTypings?: string[];
}; };

View File

@ -1,18 +1,23 @@
#!/usr/bin/env node #!/usr/bin/env node
import * as promisify from 'es6-promisify';
import * as fs from 'fs'; import * as fs from 'fs';
import lernaGetPackages = require('lerna-get-packages'); import lernaGetPackages = require('lerna-get-packages');
import * as _ from 'lodash'; import * as _ from 'lodash';
import * as moment from 'moment'; import * as moment from 'moment';
import opn = require('opn');
import * as path from 'path'; import * as path from 'path';
import { exec as execAsync, spawn } from 'promisify-child-process'; import { exec as execAsync, spawn } from 'promisify-child-process';
import * as prompt from 'prompt';
import semverDiff = require('semver-diff'); import semverDiff = require('semver-diff');
import semverSort = require('semver-sort'); import semverSort = require('semver-sort');
import { constants } from './constants'; import { constants } from './constants';
import { Changelog, Changes, SemVerIndex, UpdatedPackage } from './types'; import { Changelog, Changes, PackageToVersionChange, SemVerIndex, UpdatedPackage } from './types';
import { utils } from './utils'; import { utils } from './utils';
const DOC_GEN_COMMAND = 'docs:json';
const NPM_NAMESPACE = '@0xproject/';
const IS_DRY_RUN = process.env.IS_DRY_RUN === 'true'; const IS_DRY_RUN = process.env.IS_DRY_RUN === 'true';
const TODAYS_TIMESTAMP = moment().unix(); const TODAYS_TIMESTAMP = moment().unix();
const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js';
@ -21,8 +26,95 @@ const semverNameToIndex: { [semver: string]: number } = {
minor: SemVerIndex.Minor, minor: SemVerIndex.Minor,
major: SemVerIndex.Major, major: SemVerIndex.Major,
}; };
const packageNameToWebsitePath: { [name: string]: string } = {
'0x.js': '0xjs',
'web3-wrapper': 'web3_wrapper',
contracts: 'contracts',
connect: 'connect',
'json-schemas': 'json-schemas',
deployer: 'deployer',
'sol-cov': 'sol-cov',
subproviders: 'subproviders',
};
(async () => { (async () => {
// Fetch public, updated Lerna packages
const updatedPublicLernaPackages = await getUpdatedPublicLernaPackagesAsync();
await confirmDocPagesRenderAsync(updatedPublicLernaPackages);
// Update CHANGELOGs
const updatedPublicLernaPackageNames = _.map(updatedPublicLernaPackages, pkg => pkg.package.name);
utils.log(`Will update CHANGELOGs and publish: \n${updatedPublicLernaPackageNames.join('\n')}\n`);
const packageToVersionChange = await updateChangeLogsAsync(updatedPublicLernaPackages);
// Push changelog changes to Github
if (!IS_DRY_RUN) {
await pushChangelogsToGithubAsync();
}
// Call LernaPublish
utils.log('Version updates to apply:');
_.each(packageToVersionChange, (versionChange: string, packageName: string) => {
utils.log(`${packageName} -> ${versionChange}`);
});
utils.log(`Calling 'lerna publish'...`);
await lernaPublishAsync(packageToVersionChange);
})().catch(err => {
utils.log(err);
process.exit(1);
});
async function confirmDocPagesRenderAsync(packages: LernaPackage[]) {
// push docs to staging
utils.log("Upload all docJson's to S3 staging...");
await execAsync(`yarn lerna:stage_docs`, { cwd: constants.monorepoRootPath });
// deploy website to staging
utils.log('Deploy website to staging...');
const pathToWebsite = `${constants.monorepoRootPath}/packages/website`;
await execAsync(`yarn deploy_staging`, { cwd: pathToWebsite });
const packagesWithDocs = _.filter(packages, pkg => {
const scriptsIfExists = pkg.package.scripts;
if (_.isUndefined(scriptsIfExists)) {
throw new Error('Found a public package without any scripts in package.json');
}
return !_.isUndefined(scriptsIfExists[DOC_GEN_COMMAND]);
});
_.each(packagesWithDocs, pkg => {
const name = pkg.package.name;
const nameWithoutPrefix = _.startsWith(name, NPM_NAMESPACE) ? name.split('@0xproject/')[1] : name;
const docSegmentIfExists = packageNameToWebsitePath[nameWithoutPrefix];
if (_.isUndefined(docSegmentIfExists)) {
throw new Error(
`Found package '${name}' with doc commands but no corresponding docSegment in monorepo_scripts
package.ts. Please add an entry for it and try again.`,
);
}
const link = `${constants.stagingWebsite}/docs/${docSegmentIfExists}`;
// tslint:disable-next-line:no-floating-promises
opn(link);
});
prompt.start();
const message = 'Do all the doc pages render properly? (yn)';
const result = await promisify(prompt.get)([message]);
const didConfirm = result[message] === 'y';
if (!didConfirm) {
utils.log('Publish process aborted.');
process.exit(0);
}
}
async function pushChangelogsToGithubAsync() {
await execAsync(`git add . --all`, { cwd: constants.monorepoRootPath });
await execAsync(`git commit -m "Updated CHANGELOGS"`, { cwd: constants.monorepoRootPath });
await execAsync(`git push`, { cwd: constants.monorepoRootPath });
utils.log(`Pushed CHANGELOG updates to Github`);
}
async function getUpdatedPublicLernaPackagesAsync(): Promise<LernaPackage[]> {
const updatedPublicPackages = await getPublicLernaUpdatedPackagesAsync(); const updatedPublicPackages = await getPublicLernaUpdatedPackagesAsync();
const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name); const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name);
@ -30,10 +122,11 @@ const semverNameToIndex: { [semver: string]: number } = {
const updatedPublicLernaPackages = _.filter(allLernaPackages, pkg => { const updatedPublicLernaPackages = _.filter(allLernaPackages, pkg => {
return _.includes(updatedPackageNames, pkg.package.name); return _.includes(updatedPackageNames, pkg.package.name);
}); });
const updatedPublicLernaPackageNames = _.map(updatedPublicLernaPackages, pkg => pkg.package.name); return updatedPublicLernaPackages;
utils.log(`Will update CHANGELOGs and publish: \n${updatedPublicLernaPackageNames.join('\n')}\n`); }
const packageToVersionChange: { [name: string]: string } = {}; async function updateChangeLogsAsync(updatedPublicLernaPackages: LernaPackage[]): Promise<PackageToVersionChange> {
const packageToVersionChange: PackageToVersionChange = {};
for (const lernaPackage of updatedPublicLernaPackages) { for (const lernaPackage of updatedPublicLernaPackages) {
const packageName = lernaPackage.package.name; const packageName = lernaPackage.package.name;
const changelogJSONPath = path.join(lernaPackage.location, 'CHANGELOG.json'); const changelogJSONPath = path.join(lernaPackage.location, 'CHANGELOG.json');
@ -88,23 +181,8 @@ const semverNameToIndex: { [semver: string]: number } = {
utils.log(`${packageName}: Updated CHANGELOG.md`); utils.log(`${packageName}: Updated CHANGELOG.md`);
} }
if (!IS_DRY_RUN) { return packageToVersionChange;
await execAsync(`git add . --all`, { cwd: constants.monorepoRootPath }); }
await execAsync(`git commit -m "Updated CHANGELOGS"`, { cwd: constants.monorepoRootPath });
await execAsync(`git push`, { cwd: constants.monorepoRootPath });
utils.log(`Pushed CHANGELOG updates to Github`);
}
utils.log('Version updates to apply:');
_.each(packageToVersionChange, (versionChange: string, packageName: string) => {
utils.log(`${packageName} -> ${versionChange}`);
});
utils.log(`Calling 'lerna publish'...`);
await lernaPublishAsync(packageToVersionChange);
})().catch(err => {
utils.log(err);
process.exit(1);
});
async function lernaPublishAsync(packageToVersionChange: { [name: string]: string }) { async function lernaPublishAsync(packageToVersionChange: { [name: string]: string }) {
// HACK: Lerna publish does not provide a way to specify multiple package versions via // HACK: Lerna publish does not provide a way to specify multiple package versions via

View File

@ -21,3 +21,7 @@ export enum SemVerIndex {
Minor, Minor,
Major, Major,
} }
export interface PackageToVersionChange {
[name: string]: string;
}

View File

@ -2,7 +2,7 @@
A Solidity code coverage tool. A Solidity code coverage tool.
### Read the [Documentation](0xproject.com/docs/sol-cov). ### Read the [Documentation](https://0xproject.com/docs/sol-cov).
## Installation ## Installation

View File

@ -4,7 +4,7 @@ A few useful web3 subproviders including a LedgerSubprovider useful for adding L
We have written up a [Wiki](https://0xproject.com/wiki#Web3-Provider-Examples) article detailing some use cases of this subprovider package. We have written up a [Wiki](https://0xproject.com/wiki#Web3-Provider-Examples) article detailing some use cases of this subprovider package.
### Read the [Documentation](0xproject.com/docs/subproviders). ### Read the [Documentation](https://0xproject.com/docs/subproviders).
## Installation ## Installation

View File

@ -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;
},
};

View File

@ -5,3 +5,4 @@ export { intervalUtils } from './interval_utils';
export { BigNumber } from './configured_bignumber'; export { BigNumber } from './configured_bignumber';
export { AbiDecoder } from './abi_decoder'; export { AbiDecoder } from './abi_decoder';
export { logUtils } from './log_utils'; export { logUtils } from './log_utils';
export { abiUtils } from './abi_utils';

View File

@ -2,7 +2,7 @@
Wrapped version of web3 with a nicer interface that is used across 0x projects and packages. Wrapped version of web3 with a nicer interface that is used across 0x projects and packages.
### Read the [Documentation](0xproject.com/docs/web3_wrapper). ### Read the [Documentation](https://0xproject.com/docs/web3_wrapper).
## Installation ## Installation

View File

@ -6,7 +6,7 @@
"types": "lib/src/index.d.ts", "types": "lib/src/index.d.ts",
"scripts": { "scripts": {
"build:watch": "tsc -w", "build:watch": "tsc -w",
"build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts", "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
"clean": "shx rm -rf lib scripts", "clean": "shx rm -rf lib scripts",
"lint": "tslint --project . 'src/**/*.ts'", "lint": "tslint --project . 'src/**/*.ts'",
"test": "run-s clean build run_mocha", "test": "run-s clean build run_mocha",

185
yarn.lock
View File

@ -6,6 +6,41 @@
version "0.3.9" version "0.3.9"
resolved "https://registry.yarnpkg.com/8fold-marked/-/8fold-marked-0.3.9.tgz#bb89c645612f8ccfaffac1ca6e3c11f168c9cf59" resolved "https://registry.yarnpkg.com/8fold-marked/-/8fold-marked-0.3.9.tgz#bb89c645612f8ccfaffac1ca6e3c11f168c9cf59"
"@0xproject/dev-utils@^0.2.1":
version "0.2.1"
resolved "https://registry.yarnpkg.com/@0xproject/dev-utils/-/dev-utils-0.2.1.tgz#a54465376fd7c8cf58781b02b1790d74fb51e91b"
dependencies:
"@0xproject/subproviders" "^0.7.0"
"@0xproject/types" "^0.3.1"
"@0xproject/utils" "^0.4.1"
ethereumjs-util "^5.1.2"
lodash "^4.17.4"
request-promise-native "^1.0.5"
web3 "^0.20.0"
web3-provider-engine "^13.0.1"
"@0xproject/subproviders@^0.7.0":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@0xproject/subproviders/-/subproviders-0.7.0.tgz#ce3379a85649773e5c08f5fc3239e8ed07f13361"
dependencies:
"@0xproject/assert" "^0.2.0"
"@0xproject/types" "^0.3.1"
"@0xproject/utils" "^0.4.1"
"@ledgerhq/hw-app-eth" "^4.3.0"
"@ledgerhq/hw-transport-u2f" "^4.3.0"
bn.js "^4.11.8"
es6-promisify "^5.0.0"
ethereumjs-tx "^1.3.3"
ethereumjs-util "^5.1.1"
hdkey "^0.7.1"
lodash "^4.17.4"
semaphore-async-await "^1.5.1"
web3 "^0.20.0"
web3-provider-engine "^13.0.1"
web3-typescript-typings "^0.10.0"
optionalDependencies:
"@ledgerhq/hw-transport-node-hid" "^4.3.0"
"@0xproject/tslint-config@0.4.13": "@0xproject/tslint-config@0.4.13":
version "0.4.13" version "0.4.13"
resolved "https://registry.yarnpkg.com/@0xproject/tslint-config/-/tslint-config-0.4.13.tgz#98c71c5ae5e80315a23eda0134cc9f6f4438cac2" resolved "https://registry.yarnpkg.com/@0xproject/tslint-config/-/tslint-config-0.4.13.tgz#98c71c5ae5e80315a23eda0134cc9f6f4438cac2"
@ -15,6 +50,40 @@
tslint-eslint-rules "^4.1.1" tslint-eslint-rules "^4.1.1"
tslint-react "^3.2.0" tslint-react "^3.2.0"
"@0xproject/types@^0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@0xproject/types/-/types-0.3.1.tgz#9a75be6d3a2d41b7ecbd9105c3fdc09f3e3ec297"
dependencies:
bignumber.js "~4.1.0"
web3 "^0.20.0"
web3-typescript-typings "^0.10.0"
"@0xproject/types@^0.4.2":
version "0.4.2"
resolved "https://registry.yarnpkg.com/@0xproject/types/-/types-0.4.2.tgz#83d6ebef60f41e6209acb2656b1d68ff79367ca5"
dependencies:
bignumber.js "~4.1.0"
"@0xproject/typescript-typings@^0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@0xproject/typescript-typings/-/typescript-typings-0.0.2.tgz#b549ea3c81ce2d81b99f05583bdf7c411a3ca90c"
dependencies:
"@0xproject/types" "^0.4.2"
bignumber.js "~4.1.0"
"@0xproject/utils@^0.4.1":
version "0.4.4"
resolved "https://registry.yarnpkg.com/@0xproject/utils/-/utils-0.4.4.tgz#bce4f7a5a46570a69911f4a4ade5d49016330087"
dependencies:
"@0xproject/types" "^0.4.2"
"@0xproject/typescript-typings" "^0.0.2"
"@types/node" "^8.0.53"
bignumber.js "~4.1.0"
ethers-contracts "^2.2.1"
js-sha3 "^0.7.0"
lodash "^4.17.4"
web3 "^0.20.0"
"@ledgerhq/hw-app-eth@^4.3.0": "@ledgerhq/hw-app-eth@^4.3.0":
version "4.7.3" version "4.7.3"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-4.7.3.tgz#d352e19658ae296532e522c53c8ec2a1a77b64e5" resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-4.7.3.tgz#d352e19658ae296532e522c53c8ec2a1a77b64e5"
@ -220,6 +289,12 @@
version "8.10.0" version "8.10.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.0.tgz#f5d649cc49af8ed6507d15dc6e9b43fe8b927540" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.0.tgz#f5d649cc49af8ed6507d15dc6e9b43fe8b927540"
"@types/opn@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@types/opn/-/opn-5.1.0.tgz#bff7bc371677f4bdbb37884400e03fd81f743927"
dependencies:
"@types/node" "*"
"@types/query-string@^5.0.1": "@types/query-string@^5.0.1":
version "5.1.0" version "5.1.0"
resolved "https://registry.yarnpkg.com/@types/query-string/-/query-string-5.1.0.tgz#7f40cdea49ddafa0ea4f3db35fb6c24d3bfd4dcc" resolved "https://registry.yarnpkg.com/@types/query-string/-/query-string-5.1.0.tgz#7f40cdea49ddafa0ea4f3db35fb6c24d3bfd4dcc"
@ -734,10 +809,14 @@ async@2.6.0, async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0:
dependencies: dependencies:
lodash "^4.14.0" lodash "^4.14.0"
async@^0.9.0: async@^0.9.0, async@~0.9.0:
version "0.9.2" version "0.9.2"
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
async@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9"
async@~1.2.1: async@~1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/async/-/async-1.2.1.tgz#a4816a17cd5ff516dfa2c7698a453369b9790de0" resolved "https://registry.yarnpkg.com/async/-/async-1.2.1.tgz#a4816a17cd5ff516dfa2c7698a453369b9790de0"
@ -2151,6 +2230,10 @@ colormin@^1.0.5:
css-color-names "0.0.4" css-color-names "0.0.4"
has "^1.0.1" has "^1.0.1"
colors@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
colors@1.1.2, colors@~1.1.2: colors@1.1.2, colors@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
@ -2741,6 +2824,10 @@ currently-unhandled@^0.4.1:
dependencies: dependencies:
array-find-index "^1.0.1" array-find-index "^1.0.1"
cycle@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"
cyclist@~0.2.2: cyclist@~0.2.2:
version "0.2.2" version "0.2.2"
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
@ -2906,6 +2993,10 @@ deep-equal@^1.0.0, deep-equal@^1.0.1, deep-equal@~1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
deep-equal@~0.2.1:
version "0.2.2"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d"
deep-extend@~0.4.0: deep-extend@~0.4.0:
version "0.4.2" version "0.4.2"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
@ -3562,7 +3653,7 @@ ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumjs-util@^4.4.0:
rlp "^2.0.0" rlp "^2.0.0"
secp256k1 "^3.0.1" secp256k1 "^3.0.1"
ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5: ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5:
version "5.1.5" version "5.1.5"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz#2f02575852627d45622426f25ee4a0b5f377f27a" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz#2f02575852627d45622426f25ee4a0b5f377f27a"
dependencies: dependencies:
@ -3847,6 +3938,10 @@ extsprintf@^1.2.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
eyes@0.1.x:
version "0.1.8"
resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
fake-merkle-patricia-tree@^1.0.1, fake-merkle-patricia-tree@~1.0.1: fake-merkle-patricia-tree@^1.0.1, fake-merkle-patricia-tree@~1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3"
@ -5034,6 +5129,10 @@ hyphenate-style-name@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b"
i@0.3.x:
version "0.3.6"
resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d"
iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@~0.4.13: iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@~0.4.13:
version "0.4.19" version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
@ -5597,7 +5696,7 @@ isomorphic-fetch@^2.1.1, isomorphic-fetch@^2.2.0, isomorphic-fetch@^2.2.1:
node-fetch "^1.0.1" node-fetch "^1.0.1"
whatwg-fetch ">=0.10.0" whatwg-fetch ">=0.10.0"
isstream@~0.1.2: isstream@0.1.x, isstream@~0.1.2:
version "0.1.2" version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@ -6771,7 +6870,7 @@ mkdirp-promise@^5.0.1:
dependencies: dependencies:
mkdirp "*" mkdirp "*"
mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
version "0.5.1" version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies: dependencies:
@ -6909,6 +7008,10 @@ natives@^1.1.0:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.2.tgz#4437ca1ed8a7f047531ccdfaf2792853df4efa1c" resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.2.tgz#4437ca1ed8a7f047531ccdfaf2792853df4efa1c"
ncp@1.0.x:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246"
negotiator@0.6.1: negotiator@0.6.1:
version "0.6.1" version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
@ -7326,7 +7429,7 @@ opn@^4.0.0:
object-assign "^4.0.1" object-assign "^4.0.1"
pinkie-promise "^2.0.0" pinkie-promise "^2.0.0"
opn@^5.1.0: opn@^5.1.0, opn@^5.3.0:
version "5.3.0" version "5.3.0"
resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c"
dependencies: dependencies:
@ -7683,10 +7786,14 @@ pkg-dir@^2.0.0:
dependencies: dependencies:
find-up "^2.1.0" find-up "^2.1.0"
pkginfo@^0.3.0: pkginfo@0.3.x, pkginfo@^0.3.0:
version "0.3.1" version "0.3.1"
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21"
pkginfo@0.x.x:
version "0.4.1"
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff"
plur@^2.1.2: plur@^2.1.2:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a"
@ -8176,6 +8283,17 @@ promisify-child-process@^1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/promisify-child-process/-/promisify-child-process-1.0.5.tgz#817ad1aec92c013d83bb37e1f143e9b4033d9669" resolved "https://registry.yarnpkg.com/promisify-child-process/-/promisify-child-process-1.0.5.tgz#817ad1aec92c013d83bb37e1f143e9b4033d9669"
prompt@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe"
dependencies:
colors "^1.1.2"
pkginfo "0.x.x"
read "1.0.x"
revalidator "0.1.x"
utile "0.3.x"
winston "2.1.x"
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1: prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1:
version "15.6.1" version "15.6.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
@ -8648,7 +8766,7 @@ read-pkg@^3.0.0:
normalize-package-data "^2.3.2" normalize-package-data "^2.3.2"
path-type "^3.0.0" path-type "^3.0.0"
read@~1.0.5: read@1.0.x, read@~1.0.5:
version "1.0.7" version "1.0.7"
resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
dependencies: dependencies:
@ -8870,6 +8988,20 @@ request-ip@~1.2.3:
version "1.2.3" version "1.2.3"
resolved "https://registry.yarnpkg.com/request-ip/-/request-ip-1.2.3.tgz#66988f0e22406ec4af630d19b573fe4b447c3b49" resolved "https://registry.yarnpkg.com/request-ip/-/request-ip-1.2.3.tgz#66988f0e22406ec4af630d19b573fe4b447c3b49"
request-promise-core@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6"
dependencies:
lodash "^4.13.1"
request-promise-native@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5"
dependencies:
request-promise-core "1.1.1"
stealthy-require "^1.1.0"
tough-cookie ">=2.3.3"
request@2.81.0: request@2.81.0:
version "2.81.0" version "2.81.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
@ -9014,13 +9146,17 @@ ret@~0.1.10:
version "0.1.15" version "0.1.15"
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
revalidator@0.1.x:
version "0.1.8"
resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b"
right-align@^0.1.1: right-align@^0.1.1:
version "0.1.3" version "0.1.3"
resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
dependencies: dependencies:
align-text "^0.1.1" align-text "^0.1.1"
rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
version "2.6.2" version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies: dependencies:
@ -9732,7 +9868,7 @@ stack-trace@0.0.9:
version "0.0.9" version "0.0.9"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695"
stack-trace@~0.0.9: stack-trace@0.0.x, stack-trace@~0.0.9:
version "0.0.10" version "0.0.10"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
@ -9751,6 +9887,10 @@ static-extend@^0.1.1:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
stealthy-require@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
stream-browserify@^2.0.1: stream-browserify@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db"
@ -10323,7 +10463,7 @@ touch@^3.1.0:
dependencies: dependencies:
nopt "~1.0.10" nopt "~1.0.10"
tough-cookie@~2.3.0, tough-cookie@~2.3.3: tough-cookie@>=2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3:
version "2.3.4" version "2.3.4"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
dependencies: dependencies:
@ -10855,6 +10995,17 @@ util@0.10.3, util@^0.10.3:
dependencies: dependencies:
inherits "2.0.1" inherits "2.0.1"
utile@0.3.x:
version "0.3.0"
resolved "https://registry.yarnpkg.com/utile/-/utile-0.3.0.tgz#1352c340eb820e4d8ddba039a4fbfaa32ed4ef3a"
dependencies:
async "~0.9.0"
deep-equal "~0.2.1"
i "0.3.x"
mkdirp "0.x.x"
ncp "1.0.x"
rimraf "2.x.x"
utils-merge@1.0.1: utils-merge@1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
@ -11267,7 +11418,7 @@ web3-shh@1.0.0-beta.33:
web3-core-subscriptions "1.0.0-beta.33" web3-core-subscriptions "1.0.0-beta.33"
web3-net "1.0.0-beta.33" web3-net "1.0.0-beta.33"
web3-typescript-typings@^0.10.2: web3-typescript-typings@^0.10.0, web3-typescript-typings@^0.10.2:
version "0.10.2" version "0.10.2"
resolved "https://registry.yarnpkg.com/web3-typescript-typings/-/web3-typescript-typings-0.10.2.tgz#a9903815d2a8a0dbd73fd5db374070de0bd30497" resolved "https://registry.yarnpkg.com/web3-typescript-typings/-/web3-typescript-typings-0.10.2.tgz#a9903815d2a8a0dbd73fd5db374070de0bd30497"
dependencies: dependencies:
@ -11481,6 +11632,18 @@ window-size@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075"
winston@2.1.x:
version "2.1.1"
resolved "https://registry.yarnpkg.com/winston/-/winston-2.1.1.tgz#3c9349d196207fd1bdff9d4bc43ef72510e3a12e"
dependencies:
async "~1.0.0"
colors "1.0.x"
cycle "1.0.x"
eyes "0.1.x"
isstream "0.1.x"
pkginfo "0.3.x"
stack-trace "0.0.x"
word-wrap@1.2.3: word-wrap@1.2.3:
version "1.2.3" version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"