Merge branch 'development' into moveOutDocGenerator

* development: (36 commits)
  Fix english translations
  Fix footer on mobile
  re-add google analytics code
  Fix Russian translation
  Move all dependencies on @0xproject/types out of devDependencies
  Slight improvement to footer
  Fix a few Korean translations
  Address feedback
  Use source tree hash instead of compile flag
  Fix race condition
  Update CHANGELOG
  Delete artifacts directory
  Add generated contract artifacts to gitignore
  Check dependencies when determining if should be recompiled
  Update CHANGELOG
  Remove unused CHANGELOG entry
  Remove unused import
  Change assert.doesConformToShema interface
  Remove a type assertion
  Publish
  ...
This commit is contained in:
Fabio Berger
2018-02-25 18:32:12 -08:00
65 changed files with 465 additions and 4524 deletions

3
.gitignore vendored
View File

@@ -71,3 +71,6 @@ packages/website/public/bundle*
# generated binaries
bin/
# generated contract artifacts
packages/contracts/src/artifacts

View File

@@ -1,5 +1,5 @@
lib
generated
.nyc_output
/packages/contracts/build/contracts
/packages/contracts/src/artifacts
package.json

View File

@@ -16,7 +16,7 @@
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
},
"devDependencies": {
"@0xproject/utils": "^0.3.2",
"@0xproject/utils": "^0.3.4",
"async-child-process": "^1.1.1",
"ethereumjs-testrpc": "^6.0.3",
"lerna": "^2.5.1",

View File

@@ -1,5 +1,9 @@
# CHANGELOG
## v0.33.0 - _TBD, 2018_
* Improve validation to force passing contract addresses on private networks (#385)
## v0.32.2 - _February 9, 2018_
* Fix publishing issue where .npmignore was not properly excluding undesired content (#389)

View File

@@ -1,6 +1,6 @@
{
"name": "0x.js",
"version": "0.32.3",
"version": "0.32.4",
"description": "A javascript library for interacting with the 0x protocol",
"keywords": [
"0x.js",
@@ -42,8 +42,8 @@
"node": ">=6.0.0"
},
"devDependencies": {
"@0xproject/abi-gen": "^0.2.2",
"@0xproject/dev-utils": "^0.0.13",
"@0xproject/abi-gen": "^0.2.3",
"@0xproject/dev-utils": "^0.1.0",
"@0xproject/tslint-config": "^0.4.9",
"@types/bintrees": "^1.0.2",
"@types/jsonschema": "^1.1.1",
@@ -77,15 +77,15 @@
"types-bn": "^0.0.1",
"typescript": "2.7.1",
"web3-provider-engine": "^13.0.1",
"web3-typescript-typings": "^0.9.10",
"web3-typescript-typings": "^0.9.11",
"webpack": "^3.1.0"
},
"dependencies": {
"@0xproject/assert": "^0.0.19",
"@0xproject/json-schemas": "^0.7.11",
"@0xproject/types": "^0.2.2",
"@0xproject/utils": "^0.3.3",
"@0xproject/web3-wrapper": "^0.1.13",
"@0xproject/assert": "^0.0.20",
"@0xproject/json-schemas": "^0.7.12",
"@0xproject/types": "^0.2.3",
"@0xproject/utils": "^0.3.4",
"@0xproject/web3-wrapper": "^0.1.14",
"bintrees": "^1.0.2",
"bn.js": "^4.11.8",
"ethereumjs-abi": "^0.6.4",

View File

@@ -13,6 +13,8 @@ import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_pr
import { TokenWrapper } from './contract_wrappers/token_wrapper';
import { OrderStateWatcher } from './order_watcher/order_state_watcher';
import { zeroExConfigSchema } from './schemas/zero_ex_config_schema';
import { zeroExPrivateNetworkConfigSchema } from './schemas/zero_ex_private_network_config_schema';
import { zeroExPublicNetworkConfigSchema } from './schemas/zero_ex_public_network_config_schema';
import { ECSignature, Order, SignedOrder, Web3Provider, ZeroExConfig, ZeroExError } from './types';
import { assert } from './utils/assert';
import { constants } from './utils/constants';
@@ -163,7 +165,10 @@ export class ZeroEx {
*/
constructor(provider: Web3Provider, config: ZeroExConfig) {
assert.isWeb3Provider('provider', provider);
assert.doesConformToSchema('config', config, zeroExConfigSchema);
assert.doesConformToSchema('config', config, zeroExConfigSchema, [
zeroExPrivateNetworkConfigSchema,
zeroExPublicNetworkConfigSchema,
]);
const artifactJSONs = _.values(artifacts);
const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
this._abiDecoder = new AbiDecoder(abiArrays);

View File

@@ -1,27 +1,5 @@
export const zeroExConfigSchema = {
id: '/ZeroExConfig',
properties: {
networkId: {
type: 'number',
minimum: 0,
},
gasPrice: { $ref: '/Number' },
exchangeContractAddress: { $ref: '/Address' },
tokenRegistryContractAddress: { $ref: '/Address' },
orderWatcherConfig: {
type: 'object',
properties: {
pollingIntervalMs: {
type: 'number',
minimum: 0,
},
numConfirmations: {
type: 'number',
minimum: 0,
},
},
},
},
oneOf: [{ $ref: '/ZeroExPrivateNetworkConfig' }, { $ref: '/ZeroExPublicNetworkConfig' }],
type: 'object',
required: ['networkId'],
};

View File

@@ -0,0 +1,35 @@
export const zeroExPrivateNetworkConfigSchema = {
id: '/ZeroExPrivateNetworkConfig',
properties: {
networkId: {
type: 'number',
minimum: 1,
},
gasPrice: { $ref: '/Number' },
zrxContractAddress: { $ref: '/Address' },
exchangeContractAddress: { $ref: '/Address' },
tokenRegistryContractAddress: { $ref: '/Address' },
tokenTransferProxyContractAddress: { $ref: '/Address' },
orderWatcherConfig: {
type: 'object',
properties: {
pollingIntervalMs: {
type: 'number',
minimum: 0,
},
numConfirmations: {
type: 'number',
minimum: 0,
},
},
},
},
type: 'object',
required: [
'networkId',
'zrxContractAddress',
'exchangeContractAddress',
'tokenRegistryContractAddress',
'tokenTransferProxyContractAddress',
],
};

View File

@@ -0,0 +1,29 @@
export const zeroExPublicNetworkConfigSchema = {
id: '/ZeroExPublicNetworkConfig',
properties: {
networkId: {
type: 'number',
enum: [1, 3, 4, 42, 50],
},
gasPrice: { $ref: '/Number' },
zrxContractAddress: { $ref: '/Address' },
exchangeContractAddress: { $ref: '/Address' },
tokenRegistryContractAddress: { $ref: '/Address' },
tokenTransferProxyContractAddress: { $ref: '/Address' },
orderWatcherConfig: {
type: 'object',
properties: {
pollingIntervalMs: {
type: 'number',
minimum: 0,
},
numConfirmations: {
type: 'number',
minimum: 0,
},
},
},
},
type: 'object',
required: ['networkId'],
};

View File

@@ -196,7 +196,7 @@ export interface OrderStateWatcherConfig {
}
/*
* networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 42-kovan, 50-testrpc)
* networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 3-ropsten, 4-rinkeby, 42-kovan, 50-testrpc)
* gasPrice: Gas price to use with every transaction
* exchangeContractAddress: The address of an exchange contract to use
* zrxContractAddress: The address of the ZRX contract to use

View File

@@ -75,11 +75,14 @@ describe('EtherTokenWrapper', () => {
const contractAddressIfExists = zeroEx.etherToken.getContractAddressIfExists();
expect(contractAddressIfExists).to.not.be.undefined();
});
it('should return undefined if connected to an unknown network', () => {
it('should throw if connected to a private network and contract addresses are not specified', () => {
const UNKNOWN_NETWORK_NETWORK_ID = 10;
const unknownNetworkZeroEx = new ZeroEx(web3.currentProvider, { networkId: UNKNOWN_NETWORK_NETWORK_ID });
const contractAddressIfExists = unknownNetworkZeroEx.etherToken.getContractAddressIfExists();
expect(contractAddressIfExists).to.be.undefined();
expect(
() =>
new ZeroEx(web3.currentProvider, {
networkId: UNKNOWN_NETWORK_NETWORK_ID,
} as any),
).to.throw();
});
});
describe('#depositAsync', () => {

View File

@@ -9,10 +9,10 @@ import * as Web3 from 'web3';
import { ZeroEx } from '../src/0x';
import { ExpirationWatcher } from '../src/order_watcher/expiration_watcher';
import { DoneCallback, Token } from '../src/types';
import { constants } from '../src/utils/constants';
import { utils } from '../src/utils/utils';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
import { FillScenarios } from './utils/fill_scenarios';
import { reportNoErrorCallbackErrors } from './utils/report_callback_errors';
import { TokenUtils } from './utils/token_utils';

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/abi-gen",
"version": "0.2.2",
"version": "0.2.3",
"description": "Generate contract wrappers from ABI and handlebars templates",
"main": "lib/index.js",
"types": "lib/index.d.ts",
@@ -23,7 +23,7 @@
},
"homepage": "https://github.com/0xProject/0x.js/packages/abi-gen/README.md",
"dependencies": {
"@0xproject/utils": "^0.3.3",
"@0xproject/utils": "^0.3.4",
"chalk": "^2.3.0",
"glob": "^7.1.2",
"handlebars": "^4.0.11",
@@ -44,6 +44,6 @@
"shx": "^0.2.2",
"tslint": "5.8.0",
"typescript": "2.7.1",
"web3-typescript-typings": "^0.9.10"
"web3-typescript-typings": "^0.9.11"
}
}

View File

@@ -1,5 +1,9 @@
# CHANGELOG
## v0.1.0 - _TBD, 2018_
* Add an optional parameter `subSchemas` to `doesConformToSchema` method (#385)
## v0.0.18 - _February 9, 2017_
* Fix publishing issue where .npmignore was not properly excluding undesired content (#389)

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/assert",
"version": "0.0.19",
"version": "0.0.20",
"description": "Provides a standard way of performing type and schema validation across 0x projects",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
@@ -38,8 +38,8 @@
"typescript": "2.7.1"
},
"dependencies": {
"@0xproject/json-schemas": "^0.7.11",
"@0xproject/utils": "^0.3.3",
"@0xproject/json-schemas": "^0.7.12",
"@0xproject/utils": "^0.3.4",
"lodash": "^4.17.4",
"valid-url": "^1.0.9"
}

View File

@@ -66,8 +66,11 @@ export const assert = {
const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.sendAsync);
this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value));
},
doesConformToSchema(variableName: string, value: any, schema: Schema): void {
doesConformToSchema(variableName: string, value: any, schema: Schema, subSchemas?: Schema[]): void {
const schemaValidator = new SchemaValidator();
if (!_.isUndefined(subSchemas)) {
_.map(subSchemas, schemaValidator.addSchema.bind(schemaValidator));
}
const validationResult = schemaValidator.validate(value, schema);
const hasValidationErrors = validationResult.errors.length > 0;
const msg = `Expected ${variableName} to conform to schema ${schema.id}

View File

@@ -1,8 +1,13 @@
# CHANGELOG
## v0.6.0 - _TBD, 2018_
## v0.6.1 - _February 16, 2018_
* Fix JSON parse empty response (#407)
## v0.6.0 - _February 16, 2018_
* Add pagination options to HttpClient methods (#393)
* Add heartbeat configuration to WebSocketOrderbookChannel constructor (#406)
## v0.5.7 - _February 9, 2018_

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/connect",
"version": "0.5.8",
"version": "0.6.1",
"description": "A javascript library for interacting with the standard relayer api",
"keywords": [
"connect",
@@ -37,9 +37,9 @@
},
"homepage": "https://github.com/0xProject/0x.js/packages/connect/README.md",
"dependencies": {
"@0xproject/assert": "^0.0.19",
"@0xproject/json-schemas": "^0.7.11",
"@0xproject/utils": "^0.3.3",
"@0xproject/assert": "^0.0.20",
"@0xproject/json-schemas": "^0.7.12",
"@0xproject/utils": "^0.3.4",
"isomorphic-fetch": "^2.2.1",
"lodash": "^4.17.4",
"query-string": "^5.0.1",
@@ -65,6 +65,6 @@
"tslint": "5.8.0",
"typedoc": "~0.8.0",
"typescript": "2.7.1",
"web3-typescript-typings": "^0.9.10"
"web3-typescript-typings": "^0.9.11"
}
}

View File

@@ -14,7 +14,7 @@ postpublish_utils
tag = result.tag;
version = result.version;
const releaseName = postpublish_utils.getReleaseName(subPackageName, version);
return postpublish_utils.publishReleaseNotes(tag, releaseName);
return postpublish_utils.publishReleaseNotesAsync(tag, releaseName);
})
.then(function(release) {
console.log('POSTPUBLISH: Release successful, generating docs...');

View File

@@ -172,13 +172,12 @@ export class HttpClient implements Client {
body: JSON.stringify(payload),
headers,
});
const json = await response.json();
const text = await response.text();
if (!response.ok) {
const errorString = `${response.status} - ${response.statusText}\n${requestType} ${url}\n${JSON.stringify(
json,
)}`;
const errorString = `${response.status} - ${response.statusText}\n${requestType} ${url}\n${text}`;
throw Error(errorString);
}
return json;
const result = !_.isEmpty(text) ? JSON.parse(text) : undefined;
return result;
}
}

View File

@@ -17,4 +17,5 @@ export {
TokenPairsItem,
TokenPairsRequestOpts,
TokenTradeInfo,
WebSocketOrderbookChannelConfig,
} from './types';

View File

@@ -3,6 +3,7 @@ import { orderBookRequestSchema } from './orderbook_request_schema';
import { ordersRequestOptsSchema } from './orders_request_opts_schema';
import { pagedRequestOptsSchema } from './paged_request_opts_schema';
import { tokenPairsRequestOptsSchema } from './token_pairs_request_opts_schema';
import { webSocketOrderbookChannelConfigSchema } from './websocket_orderbook_channel_config_schema';
export const schemas = {
feesRequestSchema,
@@ -10,4 +11,5 @@ export const schemas = {
ordersRequestOptsSchema,
pagedRequestOptsSchema,
tokenPairsRequestOptsSchema,
webSocketOrderbookChannelConfigSchema,
};

View File

@@ -0,0 +1,10 @@
export const webSocketOrderbookChannelConfigSchema = {
id: '/WebSocketOrderbookChannelConfig',
type: 'object',
properties: {
heartbeatIntervalMs: {
type: 'number',
minimum: 10,
},
},
};

View File

@@ -43,6 +43,13 @@ export interface OrderbookChannel {
close: () => void;
}
/*
* heartbeatInterval: Interval in milliseconds that the orderbook channel should ping the underlying websocket. Default: 15000
*/
export interface WebSocketOrderbookChannelConfig {
heartbeatIntervalMs?: number;
}
/*
* baseTokenAddress: The address of token designated as the baseToken in the currency pair calculation of price
* quoteTokenAddress: The address of token designated as the quoteToken in the currency pair calculation of price

View File

@@ -3,6 +3,7 @@ import { schemas } from '@0xproject/json-schemas';
import * as _ from 'lodash';
import * as WebSocket from 'websocket';
import { schemas as clientSchemas } from './schemas/schemas';
import {
OrderbookChannel,
OrderbookChannelHandler,
@@ -10,9 +11,13 @@ import {
OrderbookChannelSubscriptionOpts,
WebsocketClientEventType,
WebsocketConnectionEventType,
WebSocketOrderbookChannelConfig,
} from './types';
import { orderbookChannelMessageParser } from './utils/orderbook_channel_message_parser';
const DEFAULT_HEARTBEAT_INTERVAL_MS = 15000;
const MINIMUM_HEARTBEAT_INTERVAL_MS = 10;
/**
* This class includes all the functionality related to interacting with a websocket endpoint
* that implements the standard relayer API v0
@@ -21,15 +26,25 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
private _apiEndpointUrl: string;
private _client: WebSocket.client;
private _connectionIfExists?: WebSocket.connection;
private _heartbeatTimerIfExists?: NodeJS.Timer;
private _subscriptionCounter = 0;
private _heartbeatIntervalMs: number;
/**
* Instantiates a new WebSocketOrderbookChannel instance
* @param url The relayer API base WS url you would like to interact with
* @param config The configuration object. Look up the type for the description.
* @return An instance of WebSocketOrderbookChannel
*/
constructor(url: string) {
constructor(url: string, config?: WebSocketOrderbookChannelConfig) {
assert.isUri('url', url);
if (!_.isUndefined(config)) {
assert.doesConformToSchema('config', config, clientSchemas.webSocketOrderbookChannelConfigSchema);
}
this._apiEndpointUrl = url;
this._heartbeatIntervalMs =
_.isUndefined(config) || _.isUndefined(config.heartbeatIntervalMs)
? DEFAULT_HEARTBEAT_INTERVAL_MS
: config.heartbeatIntervalMs;
this._client = new WebSocket.client();
}
/**
@@ -63,7 +78,7 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
connection.on(WebsocketConnectionEventType.Error, wsError => {
handler.onError(this, subscriptionOpts, wsError);
});
connection.on(WebsocketConnectionEventType.Close, () => {
connection.on(WebsocketConnectionEventType.Close, (code: number, desc: string) => {
handler.onClose(this, subscriptionOpts);
});
connection.on(WebsocketConnectionEventType.Message, message => {
@@ -80,6 +95,9 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
if (!_.isUndefined(this._connectionIfExists)) {
this._connectionIfExists.close();
}
if (!_.isUndefined(this._heartbeatTimerIfExists)) {
clearInterval(this._heartbeatTimerIfExists);
}
}
private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void) {
if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
@@ -87,6 +105,20 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
} else {
this._client.on(WebsocketClientEventType.Connect, connection => {
this._connectionIfExists = connection;
if (this._heartbeatIntervalMs >= MINIMUM_HEARTBEAT_INTERVAL_MS) {
this._heartbeatTimerIfExists = setInterval(() => {
connection.ping('');
}, this._heartbeatIntervalMs);
} else {
callback(
new Error(
`Heartbeat interval is ${
this._heartbeatIntervalMs
}ms which is less than the required minimum of ${MINIMUM_HEARTBEAT_INTERVAL_MS}ms`,
),
undefined,
);
}
callback(undefined, this._connectionIfExists);
});
this._client.on(WebsocketClientEventType.ConnectFailed, error => {

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "contracts",
"version": "2.1.12",
"version": "2.1.13",
"description": "Smart contract components of 0x protocol",
"main": "index.js",
"directories": {
@@ -9,10 +9,10 @@
},
"scripts": {
"build:watch": "tsc -w",
"prebuild": "run-s clean copy_artifacts generate_contract_wrappers",
"prebuild": "run-s clean compile copy_artifacts generate_contract_wrappers",
"copy_artifacts": "copyfiles './src/artifacts/**/*' ./lib",
"build": "tsc",
"test": "run-s compile build run_mocha",
"test": "run-s build run_mocha",
"run_mocha": "mocha 'lib/test/**/*.js' --timeout 10000 --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": "node ../deployer/lib/src/cli.js compile --contracts ${npm_package_config_contracts} --contracts-dir src/contracts --artifacts-dir src/artifacts",
@@ -36,9 +36,8 @@
},
"homepage": "https://github.com/0xProject/0x.js/packages/contracts/README.md",
"devDependencies": {
"@0xproject/dev-utils": "^0.0.13",
"@0xproject/dev-utils": "^0.1.0",
"@0xproject/tslint-config": "^0.4.9",
"@0xproject/types": "^0.2.2",
"@types/bluebird": "^3.5.3",
"@types/lodash": "^4.14.86",
"@types/node": "^8.0.53",
@@ -53,21 +52,22 @@
"dirty-chai": "^2.0.1",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"solc": "^0.4.18",
"shx": "^0.2.2",
"solc": "^0.4.18",
"tslint": "5.8.0",
"types-bn": "^0.0.1",
"types-ethereumjs-util": "0xProject/types-ethereumjs-util",
"typescript": "2.7.1",
"web3-typescript-typings": "^0.9.10",
"web3-typescript-typings": "^0.9.11",
"yargs": "^10.0.3"
},
"dependencies": {
"0x.js": "^0.32.3",
"@0xproject/deployer": "^0.0.9",
"@0xproject/json-schemas": "^0.7.11",
"@0xproject/utils": "^0.3.3",
"@0xproject/web3-wrapper": "^0.1.13",
"0x.js": "^0.32.4",
"@0xproject/deployer": "^0.1.0",
"@0xproject/json-schemas": "^0.7.12",
"@0xproject/types": "^0.2.3",
"@0xproject/utils": "^0.3.4",
"@0xproject/web3-wrapper": "^0.1.14",
"bluebird": "^3.5.0",
"bn.js": "^4.11.8",
"ethereumjs-abi": "^0.6.4",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,174 +0,0 @@
{
"contract_name": "Token",
"networks": {
"50": {
"solc_version": "0.4.18",
"keccak256": "0xe43382be55ddb9c7a28567b4cc59e35072da198e6c49a90ff1396aa8399fd61e",
"optimizer_enabled": 0,
"abi": [
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_from",
"type": "address"
},
{
"indexed": true,
"name": "_to",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": true,
"name": "_spender",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
}
],
"unlinked_binary":
"0x6060604052341561000f57600080fd5b6102ac8061001e6000396000f30060606040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063095ea7b31461007257806323b872dd146100cc57806370a0823114610145578063a9059cbb14610192578063dd62ed3e146101ec575b600080fd5b341561007d57600080fd5b6100b2600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610258565b604051808215151515815260200191505060405180910390f35b34156100d757600080fd5b61012b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610260565b604051808215151515815260200191505060405180910390f35b341561015057600080fd5b61017c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610269565b6040518082815260200191505060405180910390f35b341561019d57600080fd5b6101d2600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610270565b604051808215151515815260200191505060405180910390f35b34156101f757600080fd5b610242600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610278565b6040518082815260200191505060405180910390f35b600092915050565b60009392505050565b6000919050565b600092915050565b6000929150505600a165627a7a723058201ef98a5ecc619c89a935fee340b114a09fe44aa51aa765f4037dd3423f49d42d0029",
"updated_at": 1518645860796
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,10 @@
# CHANGELOG
## v0.0.10 - _??_
## v0.2.0 - _TBD, 2018_
* Check dependencies when determining if contracts should be recompiled (#408).
## v0.1.0 - _February 16, 2018_
* Add the ability to pass in specific contracts to compile in CLI (#400)

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/deployer",
"version": "0.0.9",
"version": "0.1.0",
"description": "Smart contract deployer of 0x protocol",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
@@ -31,18 +31,18 @@
"@0xproject/tslint-config": "^0.4.9",
"chai": "^4.0.1",
"copyfiles": "^1.2.0",
"shx": "^0.2.2",
"mocha": "^4.0.1",
"shx": "^0.2.2",
"tslint": "5.8.0",
"types-bn": "^0.0.1",
"typescript": "2.7.1",
"web3-typescript-typings": "^0.9.10"
"web3-typescript-typings": "^0.9.11"
},
"dependencies": {
"@0xproject/json-schemas": "^0.7.11",
"@0xproject/types": "^0.2.2",
"@0xproject/utils": "^0.3.3",
"@0xproject/web3-wrapper": "^0.1.13",
"@0xproject/json-schemas": "^0.7.12",
"@0xproject/types": "^0.2.3",
"@0xproject/utils": "^0.3.4",
"@0xproject/web3-wrapper": "^0.1.14",
"ethereumjs-util": "^5.1.1",
"lodash": "^4.17.4",
"solc": "^0.4.18",

View File

@@ -6,6 +6,7 @@ import * as Web3 from 'web3';
import * as yargs from 'yargs';
import { commands } from './commands';
import { constants } from './utils/constants';
import { CliOptions, CompilerOptions, DeployerOptions } from './utils/types';
const DEFAULT_OPTIMIZER_ENABLED = false;
@@ -101,7 +102,8 @@ function getContractsSetFromList(contracts: string): Set<string> {
const specifiedContracts = new Set();
const contractsArray = contracts.split(',');
_.forEach(contractsArray, contractName => {
specifiedContracts.add(contractName);
const fileName = `${contractName}${constants.SOLIDITY_FILE_EXTENSION}`;
specifiedContracts.add(fileName);
});
return specifiedContracts;
}

View File

@@ -5,32 +5,39 @@ import solc = require('solc');
import * as Web3 from 'web3';
import { binPaths } from './solc/bin_paths';
import { constants } from './utils/constants';
import { fsWrapper } from './utils/fs_wrapper';
import {
CompilerOptions,
ContractArtifact,
ContractData,
ContractNetworkData,
ContractNetworks,
ContractSourceData,
ContractSources,
ContractSpecificSourceData,
ImportContents,
} from './utils/types';
import { utils } from './utils/utils';
const SOLIDITY_FILE_EXTENSION = '.sol';
const ALL_CONTRACTS_IDENTIFIER = '*';
const SOLIDITY_VERSION_REGEX = /(?:solidity\s\^?)(\d+\.\d+\.\d+)/;
const SOLIDITY_FILE_EXTENSION_REGEX = /(.*\.sol)/;
const IMPORT_REGEX = /(import\s)/;
const DEPENDENCY_PATH_REGEX = /"([^"]+)"/; // Source: https://github.com/BlockChainCompany/soljitsu/blob/master/lib/shared.js
export class Compiler {
private _contractsDir: string;
private _networkId: number;
private _optimizerEnabled: number;
private _artifactsDir: string;
private _contractSourcesIfExists?: ContractSources;
private _solcErrors: Set<string>;
private _specifiedContracts: Set<string>;
private _contractSources?: ContractSources;
private _solcErrors: Set<string> = new Set();
private _specifiedContracts: Set<string> = new Set();
private _contractSourceData: ContractSourceData = {};
/**
* Recursively retrieves Solidity source code from directory.
* @param dirPath Directory to search.
* @return Mapping of contract name to contract source.
* @return Mapping of contract fileName to contract source.
*/
private static async _getContractSourcesAsync(dirPath: string): Promise<ContractSources> {
let dirContents: string[] = [];
@@ -40,15 +47,16 @@ export class Compiler {
throw new Error(`No directory found at ${dirPath}`);
}
let sources: ContractSources = {};
for (const name of dirContents) {
const contentPath = `${dirPath}/${name}`;
if (path.extname(name) === SOLIDITY_FILE_EXTENSION) {
for (const fileName of dirContents) {
const contentPath = `${dirPath}/${fileName}`;
if (path.extname(fileName) === constants.SOLIDITY_FILE_EXTENSION) {
try {
const opts = {
encoding: 'utf8',
};
sources[name] = await fsWrapper.readFileAsync(contentPath, opts);
utils.consoleLog(`Reading ${name} source...`);
const source = await fsWrapper.readFileAsync(contentPath, opts);
sources[fileName] = source;
utils.consoleLog(`Reading ${fileName} source...`);
} catch (err) {
utils.consoleLog(`Could not find file at ${contentPath}`);
}
@@ -60,19 +68,46 @@ export class Compiler {
...nestedSources,
};
} catch (err) {
utils.consoleLog(`${contentPath} is not a directory or ${SOLIDITY_FILE_EXTENSION} file`);
utils.consoleLog(`${contentPath} is not a directory or ${constants.SOLIDITY_FILE_EXTENSION} file`);
}
}
}
return sources;
}
/**
* Gets contract dependendencies and keccak256 hash from source.
* @param source Source code of contract.
* @return Object with contract dependencies and keccak256 hash of source.
*/
private static _getContractSpecificSourceData(source: string): ContractSpecificSourceData {
const dependencies: string[] = [];
const sourceHash = ethUtil.sha3(source);
const solcVersion = Compiler._parseSolidityVersion(source);
const contractSpecificSourceData: ContractSpecificSourceData = {
dependencies,
solcVersion,
sourceHash,
};
const lines = source.split('\n');
_.forEach(lines, line => {
if (!_.isNull(line.match(IMPORT_REGEX))) {
const dependencyMatch = line.match(DEPENDENCY_PATH_REGEX);
if (!_.isNull(dependencyMatch)) {
const dependencyPath = dependencyMatch[1];
const fileName = path.basename(dependencyPath);
contractSpecificSourceData.dependencies.push(fileName);
}
}
});
return contractSpecificSourceData;
}
/**
* Searches Solidity source code for compiler version.
* @param source Source code of contract.
* @return Solc compiler version.
*/
private static _parseSolidityVersion(source: string): string {
const solcVersionMatch = source.match(/(?:solidity\s\^?)([0-9]{1,2}[.][0-9]{1,2}[.][0-9]{1,2})/);
const solcVersionMatch = source.match(SOLIDITY_VERSION_REGEX);
if (_.isNull(solcVersionMatch)) {
throw new Error('Could not find Solidity version in source');
}
@@ -88,7 +123,7 @@ export class Compiler {
* @return The error message with directories truncated from the contract path.
*/
private static _getNormalizedErrMsg(errMsg: string): string {
const errPathMatch = errMsg.match(/(.*\.sol)/);
const errPathMatch = errMsg.match(SOLIDITY_FILE_EXTENSION_REGEX);
if (_.isNull(errPathMatch)) {
throw new Error('Could not find a path in error message');
}
@@ -107,7 +142,6 @@ export class Compiler {
this._networkId = opts.networkId;
this._optimizerEnabled = opts.optimizerEnabled;
this._artifactsDir = opts.artifactsDir;
this._solcErrors = new Set();
this._specifiedContracts = opts.specifiedContracts;
}
/**
@@ -115,68 +149,52 @@ export class Compiler {
*/
public async compileAllAsync(): Promise<void> {
await this._createArtifactsDirIfDoesNotExistAsync();
this._contractSourcesIfExists = await Compiler._getContractSourcesAsync(this._contractsDir);
const contractBaseNames = _.keys(this._contractSourcesIfExists);
const compiledContractPromises = _.map(contractBaseNames, async (contractBaseName: string): Promise<void> => {
return this._compileContractAsync(contractBaseName);
this._contractSources = await Compiler._getContractSourcesAsync(this._contractsDir);
_.forIn(this._contractSources, (source, fileName) => {
this._contractSourceData[fileName] = Compiler._getContractSpecificSourceData(source);
});
await Promise.all(compiledContractPromises);
const fileNames = this._specifiedContracts.has(ALL_CONTRACTS_IDENTIFIER)
? _.keys(this._contractSources)
: Array.from(this._specifiedContracts.values());
_.forEach(fileNames, fileName => {
this._setSourceTreeHash(fileName);
});
await Promise.all(_.map(fileNames, async fileName => this._compileContractAsync(fileName)));
this._solcErrors.forEach(errMsg => {
utils.consoleLog(errMsg);
});
}
/**
* Compiles contract and saves artifact to artifactsDir.
* @param contractBaseName Name of contract with '.sol' extension.
* @param fileName Name of contract with '.sol' extension.
*/
private async _compileContractAsync(contractBaseName: string): Promise<void> {
if (_.isUndefined(this._contractSourcesIfExists)) {
private async _compileContractAsync(fileName: string): Promise<void> {
if (_.isUndefined(this._contractSources)) {
throw new Error('Contract sources not yet initialized');
}
const contractSpecificSourceData = this._contractSourceData[fileName];
const currentArtifactIfExists = (await this._getContractArtifactIfExistsAsync(fileName)) as ContractArtifact;
const sourceHash = `0x${contractSpecificSourceData.sourceHash.toString('hex')}`;
const sourceTreeHash = `0x${contractSpecificSourceData.sourceTreeHashIfExists.toString('hex')}`;
const source = this._contractSourcesIfExists[contractBaseName];
const contractName = path.basename(contractBaseName, SOLIDITY_FILE_EXTENSION);
const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`;
const sourceHash = `0x${ethUtil.sha3(source).toString('hex')}`;
const isContractSpecified =
this._specifiedContracts.has(ALL_CONTRACTS_IDENTIFIER) || this._specifiedContracts.has(contractName);
let currentArtifactString: string;
let currentArtifact: ContractArtifact;
let oldNetworks: ContractNetworks;
let shouldCompile: boolean;
try {
const opts = {
encoding: 'utf8',
};
currentArtifactString = await fsWrapper.readFileAsync(currentArtifactPath, opts);
currentArtifact = JSON.parse(currentArtifactString);
oldNetworks = currentArtifact.networks;
const oldNetwork: ContractData = oldNetworks[this._networkId];
shouldCompile =
(_.isUndefined(oldNetwork) ||
oldNetwork.keccak256 !== sourceHash ||
oldNetwork.optimizer_enabled !== this._optimizerEnabled) &&
isContractSpecified;
} catch (err) {
shouldCompile = isContractSpecified;
}
const shouldCompile =
_.isUndefined(currentArtifactIfExists) ||
currentArtifactIfExists.networks[this._networkId].optimizer_enabled !== this._optimizerEnabled ||
currentArtifactIfExists.networks[this._networkId].source_tree_hash !== sourceTreeHash;
if (!shouldCompile) {
return;
}
const input = {
[contractBaseName]: source,
};
const solcVersion = Compiler._parseSolidityVersion(source);
const fullSolcVersion = binPaths[solcVersion];
const fullSolcVersion = binPaths[contractSpecificSourceData.solcVersion];
const solcBinPath = `./solc/solc_bin/${fullSolcVersion}`;
const solcBin = require(solcBinPath);
const solcInstance = solc.setupMethods(solcBin);
utils.consoleLog(`Compiling ${contractBaseName}...`);
utils.consoleLog(`Compiling ${fileName}...`);
const source = this._contractSources[fileName];
const input = {
[fileName]: source,
};
const sourcesToCompile = {
sources: input,
};
@@ -187,19 +205,21 @@ export class Compiler {
);
if (!_.isUndefined(compiled.errors)) {
_.each(compiled.errors, errMsg => {
_.forEach(compiled.errors, errMsg => {
const normalizedErrMsg = Compiler._getNormalizedErrMsg(errMsg);
this._solcErrors.add(normalizedErrMsg);
});
}
const contractIdentifier = `${contractBaseName}:${contractName}`;
const contractName = path.basename(fileName, constants.SOLIDITY_FILE_EXTENSION);
const contractIdentifier = `${fileName}:${contractName}`;
const abi: Web3.ContractAbi = JSON.parse(compiled.contracts[contractIdentifier].interface);
const unlinked_binary = `0x${compiled.contracts[contractIdentifier].bytecode}`;
const updated_at = Date.now();
const contractData: ContractData = {
solc_version: solcVersion,
const contractNetworkData: ContractNetworkData = {
solc_version: contractSpecificSourceData.solcVersion,
keccak256: sourceHash,
source_tree_hash: sourceTreeHash,
optimizer_enabled: this._optimizerEnabled,
abi,
unlinked_binary,
@@ -207,26 +227,56 @@ export class Compiler {
};
let newArtifact: ContractArtifact;
if (!_.isUndefined(currentArtifactString)) {
if (!_.isUndefined(currentArtifactIfExists)) {
newArtifact = {
...currentArtifact,
...currentArtifactIfExists,
networks: {
...oldNetworks,
[this._networkId]: contractData,
...currentArtifactIfExists.networks,
[this._networkId]: contractNetworkData,
},
};
} else {
newArtifact = {
contract_name: contractName,
networks: {
[this._networkId]: contractData,
[this._networkId]: contractNetworkData,
},
};
}
const artifactString = utils.stringifyWithFormatting(newArtifact);
const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`;
await fsWrapper.writeFileAsync(currentArtifactPath, artifactString);
utils.consoleLog(`${contractBaseName} artifact saved!`);
utils.consoleLog(`${fileName} artifact saved!`);
}
/**
* Sets the source tree hash for a file and its dependencies.
* @param fileName Name of contract file.
*/
private _setSourceTreeHash(fileName: string): void {
const contractSpecificSourceData = this._contractSourceData[fileName];
if (_.isUndefined(contractSpecificSourceData)) {
throw new Error(`Contract data for ${fileName} not yet set`);
}
if (_.isUndefined(contractSpecificSourceData.sourceTreeHashIfExists)) {
const dependencies = contractSpecificSourceData.dependencies;
if (dependencies.length === 0) {
contractSpecificSourceData.sourceTreeHashIfExists = contractSpecificSourceData.sourceHash;
} else {
_.forEach(dependencies, dependency => {
this._setSourceTreeHash(dependency);
});
const dependencySourceTreeHashes = _.map(
dependencies,
dependency => this._contractSourceData[dependency].sourceTreeHashIfExists,
);
const sourceTreeHashesBuffer = Buffer.concat([
contractSpecificSourceData.sourceHash,
...dependencySourceTreeHashes,
]);
contractSpecificSourceData.sourceTreeHashIfExists = ethUtil.sha3(sourceTreeHashesBuffer);
}
}
}
/**
* Callback to resolve dependencies with `solc.compile`.
@@ -235,11 +285,11 @@ export class Compiler {
* @return Import contents object containing source code of dependency.
*/
private _findImportsIfSourcesExist(importPath: string): ImportContents {
if (_.isUndefined(this._contractSourcesIfExists)) {
throw new Error('Contract sources not yet initialized');
const fileName = path.basename(importPath);
const source = this._contractSources[fileName];
if (_.isUndefined(source)) {
throw new Error(`Contract source not found for ${fileName}`);
}
const contractBaseName = path.basename(importPath);
const source = this._contractSourcesIfExists[contractBaseName];
const importContents: ImportContents = {
contents: source,
};
@@ -254,4 +304,25 @@ export class Compiler {
await fsWrapper.mkdirAsync(this._artifactsDir);
}
}
/**
* Gets contract data on network or returns if an artifact does not exist.
* @param fileName Name of contract file.
* @return Contract data on network or undefined.
*/
private async _getContractArtifactIfExistsAsync(fileName: string): Promise<ContractArtifact | void> {
let contractArtifact;
const contractName = path.basename(fileName, constants.SOLIDITY_FILE_EXTENSION);
const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`;
try {
const opts = {
encoding: 'utf8',
};
const contractArtifactString = await fsWrapper.readFileAsync(currentArtifactPath, opts);
contractArtifact = JSON.parse(contractArtifactString);
return contractArtifact;
} catch (err) {
utils.consoleLog(`Artifact for ${fileName} does not exist`);
return undefined;
}
}
}

View File

@@ -6,7 +6,7 @@ import * as Web3 from 'web3';
import { Contract } from './utils/contract';
import { encoder } from './utils/encoder';
import { fsWrapper } from './utils/fs_wrapper';
import { ContractArtifact, ContractData, DeployerOptions } from './utils/types';
import { ContractArtifact, ContractNetworkData, DeployerOptions } from './utils/types';
import { utils } from './utils/utils';
// Gas added to gas estimate to make sure there is sufficient gas for deployment.
@@ -35,9 +35,11 @@ export class Deployer {
* @return Deployed contract instance.
*/
public async deployAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> {
const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
const data = contractData.unlinked_binary;
const contractArtifactIfExists: ContractArtifact = this._loadContractArtifactIfExists(contractName);
const contractNetworkDataIfExists: ContractNetworkData = this._getContractNetworkDataFromArtifactIfExists(
contractArtifactIfExists,
);
const data = contractNetworkDataIfExists.unlinked_binary;
const from = await this._getFromAddressAsync();
const gas = await this._getAllowableGasEstimateAsync(data);
const txData = {
@@ -46,7 +48,7 @@ export class Deployer {
data,
gas,
};
const abi = contractData.abi;
const abi = contractNetworkDataIfExists.abi;
const web3ContractInstance = await this._deployFromAbiAsync(abi, args, txData);
utils.consoleLog(`${contractName}.sol successfully deployed at ${web3ContractInstance.address}`);
const contractInstance = new Contract(web3ContractInstance, this._defaults);
@@ -100,19 +102,21 @@ export class Deployer {
contractAddress: string,
args: any[],
): Promise<void> {
const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
const abi = contractData.abi;
const contractArtifactIfExists: ContractArtifact = this._loadContractArtifactIfExists(contractName);
const contractNetworkDataIfExists: ContractNetworkData = this._getContractNetworkDataFromArtifactIfExists(
contractArtifactIfExists,
);
const abi = contractNetworkDataIfExists.abi;
const encodedConstructorArgs = encoder.encodeConstructorArgsFromAbi(args, abi);
const newContractData = {
...contractData,
...contractNetworkDataIfExists,
address: contractAddress,
constructor_args: encodedConstructorArgs,
};
const newArtifact = {
...contractArtifact,
...contractArtifactIfExists,
networks: {
...contractArtifact.networks,
...contractArtifactIfExists.networks,
[this._networkId]: newContractData,
},
};
@@ -139,12 +143,12 @@ export class Deployer {
* @param contractArtifact The contract artifact.
* @return Network specific contract data.
*/
private _getContractDataFromArtifactIfExists(contractArtifact: ContractArtifact): ContractData {
const contractData = contractArtifact.networks[this._networkId];
if (_.isUndefined(contractData)) {
private _getContractNetworkDataFromArtifactIfExists(contractArtifact: ContractArtifact): ContractNetworkData {
const contractNetworkDataIfExists = contractArtifact.networks[this._networkId];
if (_.isUndefined(contractNetworkDataIfExists)) {
throw new Error(`Data not found in artifact for contract: ${contractArtifact.contract_name}`);
}
return contractData;
return contractNetworkDataIfExists;
}
/**
* Gets the address to use for sending a transaction.

View File

@@ -1,3 +1,4 @@
export const constants = {
NULL_BYTES: '0x',
SOLIDITY_FILE_EXTENSION: '.sol',
};

View File

@@ -9,7 +9,7 @@ export const encoder = {
const constructorTypes: string[] = [];
_.each(abi, (element: Web3.AbiDefinition) => {
if (element.type === AbiType.Constructor) {
_.each(element.inputs, (input: Web3.FunctionParameter) => {
_.each(element.inputs, (input: Web3.DataItem) => {
constructorTypes.push(input.type);
});
}

View File

@@ -15,13 +15,14 @@ export interface ContractArtifact {
}
export interface ContractNetworks {
[key: number]: ContractData;
[key: number]: ContractNetworkData;
}
export interface ContractData {
export interface ContractNetworkData {
solc_version: string;
optimizer_enabled: number;
keccak256: string;
source_tree_hash: string;
abi: Web3.ContractAbi;
unlinked_binary: string;
address?: string;
@@ -64,6 +65,17 @@ export interface ContractSources {
[key: string]: string;
}
export interface ContractSourceData {
[key: string]: ContractSpecificSourceData;
}
export interface ContractSpecificSourceData {
dependencies: string[];
solcVersion: string;
sourceHash: Buffer;
sourceTreeHashIfExists?: Buffer;
}
export interface ImportContents {
contents: string;
}

View File

@@ -4,7 +4,7 @@ import 'mocha';
import { Compiler } from '../src/compiler';
import { Deployer } from '../src/deployer';
import { fsWrapper } from '../src/utils/fs_wrapper';
import { CompilerOptions, ContractArtifact, ContractData, DoneCallback } from '../src/utils/types';
import { CompilerOptions, ContractArtifact, ContractNetworkData, DoneCallback } from '../src/utils/types';
import { constructor_args, exchange_binary } from './fixtures/exchange_bin';
import { constants } from './util/constants';
@@ -51,7 +51,7 @@ describe('#Compiler', () => {
};
const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
const exchangeContractData: ContractNetworkData = exchangeArtifact.networks[constants.networkId];
// The last 43 bytes of the binaries are metadata which may not be equivalent
const unlinkedBinaryWithoutMetadata = exchangeContractData.unlinked_binary.slice(0, -86);
const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -86);
@@ -68,7 +68,7 @@ describe('#Deployer', () => {
};
const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
const exchangeContractData: ContractNetworkData = exchangeArtifact.networks[constants.networkId];
const exchangeAddress = exchangeContractInstance.address;
expect(exchangeAddress).to.not.equal(undefined);
expect(exchangeContractData.address).to.equal(undefined);
@@ -84,7 +84,7 @@ describe('#Deployer', () => {
};
const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
const exchangeContractData: ContractNetworkData = exchangeArtifact.networks[constants.networkId];
const exchangeAddress = exchangeContractInstance.address;
expect(exchangeAddress).to.be.equal(exchangeContractData.address);
expect(constructor_args).to.be.equal(exchangeContractData.constructor_args);

View File

@@ -1,6 +1,6 @@
# CHANGELOG
## v0.1.0 - _TBD, 2018_
## v0.1.0 - _February 16, 2018_
* Remove subproviders (#392)

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/dev-utils",
"version": "0.0.13",
"version": "0.1.0",
"description": "0x dev TS utils",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
@@ -23,11 +23,10 @@
},
"homepage": "https://github.com/0xProject/0x.js/packages/dev-utils/README.md",
"devDependencies": {
"@types/mocha": "^2.2.42",
"@0xproject/tslint-config": "^0.4.9",
"@0xproject/types": "^0.2.2",
"@0xproject/web3-wrapper": "^0.1.13",
"@0xproject/web3-wrapper": "^0.1.14",
"@types/lodash": "^4.14.86",
"@types/mocha": "^2.2.42",
"chai": "^4.0.1",
"chai-typescript-typings": "^0.0.3",
"mocha": "^4.0.1",
@@ -39,8 +38,9 @@
"typescript": "2.7.1"
},
"dependencies": {
"@0xproject/utils": "^0.3.3",
"@0xproject/subproviders": "^0.4.2",
"@0xproject/subproviders": "^0.5.0",
"@0xproject/types": "^0.2.3",
"@0xproject/utils": "^0.3.4",
"ethereumjs-util": "^5.1.2",
"lodash": "^4.17.4",
"request-promise-native": "^1.0.5",

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/json-schemas",
"version": "0.7.11",
"version": "0.7.12",
"description": "0x-related json schemas",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
@@ -29,7 +29,7 @@
},
"devDependencies": {
"@0xproject/tslint-config": "^0.4.9",
"@0xproject/utils": "^0.3.3",
"@0xproject/utils": "^0.3.4",
"@types/lodash.foreach": "^4.5.3",
"@types/lodash.values": "^4.3.3",
"@types/mocha": "^2.2.42",

View File

@@ -1,6 +1,6 @@
# CHANGELOG
## v0.5.0 - _TBD, 2018_
## v0.5.0 - _February 16, 2018_
* Add EmptyWalletSubprovider and FakeGasEstimateSubprovider (#392)

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/subproviders",
"version": "0.4.2",
"version": "0.5.0",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"license": "Apache-2.0",
@@ -18,8 +18,9 @@
"test:integration": "run-s clean build run_mocha_integration"
},
"dependencies": {
"@0xproject/assert": "^0.0.19",
"@0xproject/utils": "^0.3.3",
"@0xproject/assert": "^0.0.20",
"@0xproject/types": "^0.2.3",
"@0xproject/utils": "^0.3.4",
"bn.js": "^4.11.8",
"es6-promisify": "^5.0.0",
"ethereumjs-tx": "^1.3.3",
@@ -33,8 +34,7 @@
},
"devDependencies": {
"@0xproject/tslint-config": "^0.4.9",
"@0xproject/types": "^0.2.2",
"@0xproject/utils": "^0.3.3",
"@0xproject/utils": "^0.3.4",
"@types/lodash": "^4.14.86",
"@types/mocha": "^2.2.42",
"@types/node": "^8.0.53",
@@ -51,7 +51,7 @@
"types-bn": "^0.0.1",
"types-ethereumjs-util": "0xProject/types-ethereumjs-util",
"typescript": "2.7.1",
"web3-typescript-typings": "^0.9.10",
"web3-typescript-typings": "^0.9.11",
"webpack": "^3.1.0"
}
}

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "@0xproject/testnet-faucets",
"version": "1.0.13",
"version": "1.0.14",
"description": "A faucet micro-service that dispenses test ERC20 tokens or Ether",
"main": "server.js",
"scripts": {
@@ -15,9 +15,9 @@
"author": "Fabio Berger",
"license": "Apache-2.0",
"dependencies": {
"0x.js": "^0.32.3",
"@0xproject/subproviders": "^0.4.2",
"@0xproject/utils": "^0.3.3",
"0x.js": "^0.32.4",
"@0xproject/subproviders": "^0.5.0",
"@0xproject/utils": "^0.3.4",
"body-parser": "^1.17.1",
"ethereumjs-tx": "^1.3.3",
"ethereumjs-util": "^5.1.1",
@@ -41,7 +41,7 @@
"types-bn": "^0.0.1",
"types-ethereumjs-util": "0xProject/types-ethereumjs-util",
"typescript": "2.7.1",
"web3-typescript-typings": "^0.9.10",
"web3-typescript-typings": "^0.9.11",
"webpack": "^3.1.0",
"webpack-node-externals": "^1.6.0"
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/types",
"version": "0.2.2",
"version": "0.2.3",
"description": "0x types",
"main": "lib/index.js",
"types": "lib/index.d.ts",
@@ -24,7 +24,7 @@
"shx": "^0.2.2",
"tslint": "5.8.0",
"typescript": "2.7.1",
"web3-typescript-typings": "^0.9.10"
"web3-typescript-typings": "^0.9.11"
},
"dependencies": {
"bignumber.js": "~4.1.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/utils",
"version": "0.3.3",
"version": "0.3.4",
"description": "0x TS utils",
"main": "lib/index.js",
"types": "lib/index.d.ts",
@@ -21,15 +21,15 @@
"homepage": "https://github.com/0xProject/0x.js/packages/utils/README.md",
"devDependencies": {
"@0xproject/tslint-config": "^0.4.9",
"@0xproject/types": "^0.2.2",
"@types/lodash": "^4.14.86",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"tslint": "5.8.0",
"typescript": "2.7.1",
"web3-typescript-typings": "^0.9.10"
"web3-typescript-typings": "^0.9.11"
},
"dependencies": {
"@0xproject/types": "^0.2.3",
"bignumber.js": "~4.1.0",
"js-sha3": "^0.7.0",
"lodash": "^4.17.4",

View File

@@ -1,11 +1,15 @@
# CHANGELOG
## v0.9.11 - _TBD, 2018_
## v0.10.0 - _TBD, 2018_
* Fix `web3.net.peerCount` to be of type number instead of boolean (#397)
* Support ABIv2 (#401)
## v0.9.11 - _February 16, 2018_
* Fix `web3.net.peerCount` to be of type number instead of boolean (#397)
## v0.9.3 - _January 11, 2018_
* Fix `getTransactionReceipt` not returning null (#338)
* Add type for getData on a contract
* Fixed the `defaultAccount` not allowing for `undefined` value (#320)
* Fix `getTransactionReceipt` not returning null (#338)
* Add type for getData on a contract
* Fixed the `defaultAccount` not allowing for `undefined` value (#320)

View File

@@ -62,8 +62,8 @@ declare module 'web3' {
interface MethodAbi {
type: AbiType.Function;
name: string;
inputs: FunctionParameter[];
outputs: FunctionParameter[];
inputs: DataItem[];
outputs: DataItem[];
constant: boolean;
stateMutability: StateMutability;
payable: boolean;
@@ -71,7 +71,7 @@ declare module 'web3' {
interface ConstructorAbi {
type: AbiType.Constructor;
inputs: FunctionParameter[];
inputs: DataItem[];
payable: boolean;
stateMutability: ConstructorStateMutability;
}
@@ -81,9 +81,7 @@ declare module 'web3' {
payable: boolean;
}
interface EventParameter {
name: string;
type: string;
interface EventParameter extends DataItem {
indexed: boolean;
}
@@ -94,9 +92,10 @@ declare module 'web3' {
anonymous: boolean;
}
interface FunctionParameter {
interface DataItem {
name: string;
type: string;
components: DataItem[];
}
interface ContractInstance {

View File

@@ -1,6 +1,6 @@
{
"name": "web3-typescript-typings",
"version": "0.9.10",
"version": "0.9.11",
"description": "Typescript type definitions for web3",
"main": "index.d.ts",
"types": "index.d.ts",

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/web3-wrapper",
"version": "0.1.13",
"version": "0.1.14",
"description": "Wraps around web3 and gives a nicer interface",
"main": "lib/index.js",
"types": "lib/index.d.ts",
@@ -21,16 +21,16 @@
"homepage": "https://github.com/0xProject/0x.js/packages/web3-wrapper/README.md",
"devDependencies": {
"@0xproject/tslint-config": "^0.4.9",
"@0xproject/types": "^0.2.2",
"@types/lodash": "^4.14.86",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"tslint": "5.8.0",
"typescript": "2.7.1",
"web3-typescript-typings": "^0.9.10"
"web3-typescript-typings": "^0.9.11"
},
"dependencies": {
"@0xproject/utils": "^0.3.3",
"@0xproject/types": "^0.2.3",
"@0xproject/utils": "^0.3.4",
"lodash": "^4.17.4",
"web3": "^0.20.0"
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/website",
"version": "0.0.15",
"version": "0.0.16",
"private": true,
"description": "Website and 0x portal dapp",
"scripts": {
@@ -18,9 +18,9 @@
"author": "Fabio Berger",
"license": "Apache-2.0",
"dependencies": {
"0x.js": "^0.32.3",
"@0xproject/subproviders": "^0.4.2",
"@0xproject/utils": "^0.3.3",
"0x.js": "^0.32.4",
"@0xproject/subproviders": "^0.5.0",
"@0xproject/utils": "^0.3.4",
"accounting": "^0.4.1",
"basscss": "^8.0.3",
"blockies": "^0.0.2",
@@ -98,7 +98,7 @@
"tslint": "5.8.0",
"tslint-config-0xproject": "^0.0.2",
"typescript": "2.7.1",
"web3-typescript-typings": "^0.9.10",
"web3-typescript-typings": "^0.9.11",
"webpack": "^3.1.0",
"webpack-dev-middleware": "^1.10.0",
"webpack-dev-server": "^2.5.0"

View File

@@ -23,6 +23,18 @@
</head>
<body style="margin: 0px; min-width: 355px;">
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-98720122-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'UA-98720122-1');
</script>
<!-- End Google Analytics -->
<!-- Facebook SDK -->
<div id="fb-root"></div>
<script>

View File

@@ -67,7 +67,7 @@
"STANDARD_RELAYER_API": "standard relayer API",
"PORTAL_DAPP": "portal dApp",
"WEBSITE": "website",
"DEVELOPERS": "home",
"HOME": "rocket.chat",
"ROCKETCHAT": "developers"
"DEVELOPERS": "developers",
"HOME": "home",
"ROCKETCHAT": "rocket.chat"
}

View File

@@ -66,7 +66,7 @@
"STANDARD_RELAYER_API": "Standard Relayer API",
"PORTAL_DAPP": "포털 dApp",
"WEBSITE": "Website",
"DEVELOPERS": "홈",
"HOME": "Rocket.chat",
"ROCKETCHAT": "개발자"
"HOME": "홈",
"ROCKETCHAT": "Rocket.chat",
"DEVELOPERS": "개발자"
}

View File

@@ -3,7 +3,7 @@
"TOP_TAGLINE": "0x — это протокол с открытым кодом, позволяющий торговать токенами ERC20, на блокчейне Ethereum.",
"BUILD_CALL_TO_ACTION": "Разрабатывайте на 0x",
"COMMUNITY_CALL_TO_ACTION": "Сообщество",
"PROJECTS_HEADER": "Прожкты разработанные на 0х",
"PROJECTS_HEADER": "Проекты разработанные на 0х",
"FULL_LIST_PROMPT": "Просмотреть",
"FULL_LIST_LINK": "полный список",
"TOKENIZED_SECTION_HEADER": "Сегодняшний мир движется к токенизации ценности",

View File

@@ -201,11 +201,9 @@ export class Footer extends React.Component<FooterProps, FooterState> {
{item.isExternal ? (
<a className="text-decoration-none" style={linkStyle} target="_blank" href={item.path}>
{!_.isUndefined(iconIfExists) ? (
<div className="sm-mx-auto" style={{ width: 65 }}>
<div className="flex">
<div className="pr1">{this._renderIcon(iconIfExists)}</div>
<div>{item.title}</div>
</div>
<div className="inline-block">
<div className="pr1 table-cell">{this._renderIcon(iconIfExists)}</div>
<div className="table-cell">{item.title}</div>
</div>
) : (
item.title

View File

@@ -64,6 +64,7 @@ const docsInfoConfig: DocsInfoConfig = {
'TokenPairsRequest',
'TokenPairsRequestOpts',
'TokenTradeInfo',
'WebSocketOrderbookChannelConfig',
'Order',
'SignedOrder',
'ECSignature',