Merge branch 'development' of github.com:0xProject/0x-monorepo into development

* 'development' of github.com:0xProject/0x-monorepo:
  Add missing type definitions
This commit is contained in:
Fabio Berger
2018-05-14 11:30:51 +02:00
153 changed files with 655 additions and 600 deletions

View File

@@ -103,6 +103,7 @@
"@0xproject/order-utils": "^0.0.4", "@0xproject/order-utils": "^0.0.4",
"@0xproject/types": "^0.6.3", "@0xproject/types": "^0.6.3",
"@0xproject/typescript-typings": "^0.3.1", "@0xproject/typescript-typings": "^0.3.1",
"@0xproject/sol-compiler": "^0.4.3",
"@0xproject/utils": "^0.6.1", "@0xproject/utils": "^0.6.1",
"@0xproject/web3-wrapper": "^0.6.3", "@0xproject/web3-wrapper": "^0.6.3",
"ethers": "^3.0.15", "ethers": "^3.0.15",

View File

@@ -200,7 +200,7 @@ export class ZeroEx {
*/ */
public async awaitTransactionMinedAsync( public async awaitTransactionMinedAsync(
txHash: string, txHash: string,
pollingIntervalMs = 1000, pollingIntervalMs: number = 1000,
timeoutMs?: number, timeoutMs?: number,
): Promise<TransactionReceiptWithDecodedLogs> { ): Promise<TransactionReceiptWithDecodedLogs> {
// Hack: Get Web3Wrapper from ContractWrappers // Hack: Get Web3Wrapper from ContractWrappers

View File

@@ -5,7 +5,7 @@ import * as path from 'path';
import { constants } from './utils/constants'; import { constants } from './utils/constants';
import { provider } from './utils/web3_wrapper'; import { provider } from './utils/web3_wrapper';
before('migrate contracts', async function() { before('migrate contracts', async function(): Promise<void> {
// HACK: Since the migrations take longer then our global mocha timeout limit // HACK: Since the migrations take longer then our global mocha timeout limit
// we manually increase it for this before hook. // we manually increase it for this before hook.
this.timeout(20000); this.timeout(20000);

View File

@@ -4,7 +4,7 @@ import ChaiBigNumber = require('chai-bignumber');
import * as dirtyChai from 'dirty-chai'; import * as dirtyChai from 'dirty-chai';
export const chaiSetup = { export const chaiSetup = {
configure() { configure(): void {
chai.config.includeStack = true; chai.config.includeStack = true;
chai.use(ChaiBigNumber()); chai.use(ChaiBigNumber());
chai.use(dirtyChai); chai.use(dirtyChai);

View File

@@ -61,14 +61,13 @@ const args = yargs
'Full usage example', 'Full usage example',
).argv; ).argv;
function registerPartials(partialsGlob: string) { function registerPartials(partialsGlob: string): void {
const partialTemplateFileNames = globSync(partialsGlob); const partialTemplateFileNames = globSync(partialsGlob);
logUtils.log(`Found ${chalk.green(`${partialTemplateFileNames.length}`)} ${chalk.bold('partial')} templates`); logUtils.log(`Found ${chalk.green(`${partialTemplateFileNames.length}`)} ${chalk.bold('partial')} templates`);
for (const partialTemplateFileName of partialTemplateFileNames) { for (const partialTemplateFileName of partialTemplateFileNames) {
const namedContent = utils.getNamedContent(partialTemplateFileName); const namedContent = utils.getNamedContent(partialTemplateFileName);
Handlebars.registerPartial(namedContent.name, namedContent.content); Handlebars.registerPartial(namedContent.name, namedContent.content);
} }
return partialsGlob;
} }
function writeOutputFile(name: string, renderedTsCode: string): void { function writeOutputFile(name: string, renderedTsCode: string): void {

View File

@@ -10,7 +10,7 @@ export const assert = {
const isBigNumber = _.isObject(value) && (value as any).isBigNumber; const isBigNumber = _.isObject(value) && (value as any).isBigNumber;
this.assert(isBigNumber, this.typeAssertionMessage(variableName, 'BigNumber', value)); this.assert(isBigNumber, this.typeAssertionMessage(variableName, 'BigNumber', value));
}, },
isValidBaseUnitAmount(variableName: string, value: BigNumber) { isValidBaseUnitAmount(variableName: string, value: BigNumber): void {
assert.isBigNumber(variableName, value); assert.isBigNumber(variableName, value);
const isNegative = value.lessThan(0); const isNegative = value.lessThan(0);
this.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`); this.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);

View File

@@ -91,7 +91,7 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
/** /**
* Close the websocket and stop receiving updates * Close the websocket and stop receiving updates
*/ */
public close() { public close(): void {
if (!_.isUndefined(this._connectionIfExists)) { if (!_.isUndefined(this._connectionIfExists)) {
this._connectionIfExists.close(); this._connectionIfExists.close();
} }
@@ -99,7 +99,7 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
clearInterval(this._heartbeatTimerIfExists); clearInterval(this._heartbeatTimerIfExists);
} }
} }
private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void) { private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void): void {
if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) { if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
callback(undefined, this._connectionIfExists); callback(undefined, this._connectionIfExists);
} else { } else {

View File

@@ -12,7 +12,7 @@ import { isValidSignature } from '@0xproject/order-utils';
export const assert = { export const assert = {
...sharedAssert, ...sharedAssert,
isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string) { isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string): void {
const isValid = isValidSignature(orderHash, ecSignature, signerAddress); const isValid = isValidSignature(orderHash, ecSignature, signerAddress);
this.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`); this.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`);
}, },

View File

@@ -39,7 +39,7 @@ const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
// Do not use arrow syntax here. Use a function expression in // Do not use arrow syntax here. Use a function expression in
// order to use the correct value of `this` in this method // order to use the correct value of `this` in this method
// tslint:disable-next-line:only-arrow-functions // tslint:disable-next-line:only-arrow-functions
descriptor.value = async function(...args: any[]) { descriptor.value = async function(...args: any[]): Promise<any> {
try { try {
const result = await originalMethod.apply(this, args); const result = await originalMethod.apply(this, args);
return result; return result;
@@ -66,7 +66,7 @@ const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
// Do not use arrow syntax here. Use a function expression in // Do not use arrow syntax here. Use a function expression in
// order to use the correct value of `this` in this method // order to use the correct value of `this` in this method
// tslint:disable-next-line:only-arrow-functions // tslint:disable-next-line:only-arrow-functions
descriptor.value = function(...args: any[]) { descriptor.value = function(...args: any[]): any {
try { try {
const result = originalMethod.apply(this, args); const result = originalMethod.apply(this, args);
return result; return result;

View File

@@ -86,12 +86,12 @@ export class OrderValidationUtils {
private static _validateRemainingFillAmountNotZeroOrThrow( private static _validateRemainingFillAmountNotZeroOrThrow(
takerTokenAmount: BigNumber, takerTokenAmount: BigNumber,
unavailableTakerTokenAmount: BigNumber, unavailableTakerTokenAmount: BigNumber,
) { ): void {
if (takerTokenAmount.eq(unavailableTakerTokenAmount)) { if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero); throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
} }
} }
private static _validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber) { private static _validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber): void {
const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec(); const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) { if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
throw new Error(ExchangeContractErrs.OrderFillExpired); throw new Error(ExchangeContractErrs.OrderFillExpired);

View File

@@ -4,7 +4,7 @@ import ChaiBigNumber = require('chai-bignumber');
import * as dirtyChai from 'dirty-chai'; import * as dirtyChai from 'dirty-chai';
export const chaiSetup = { export const chaiSetup = {
configure() { configure(): void {
chai.config.includeStack = true; chai.config.includeStack = true;
chai.use(ChaiBigNumber()); chai.use(ChaiBigNumber());
chai.use(dirtyChai); chai.use(dirtyChai);

View File

@@ -18,7 +18,7 @@ export const crypto = {
solSHA256(args: any[]): Buffer { solSHA256(args: any[]): Buffer {
return crypto._solHash(args, ABI.soliditySHA256); return crypto._solHash(args, ABI.soliditySHA256);
}, },
_solHash(args: any[], hashFunction: (types: string[], values: any[]) => Buffer) { _solHash(args: any[], hashFunction: (types: string[], values: any[]) => Buffer): Buffer {
const argTypes: string[] = []; const argTypes: string[] = [];
_.each(args, (arg, i) => { _.each(args, (arg, i) => {
const isNumber = _.isFinite(arg); const isNumber = _.isFinite(arg);

View File

@@ -9,7 +9,7 @@ export const formatters = {
signedOrders: SignedOrder[], signedOrders: SignedOrder[],
shouldThrowOnInsufficientBalanceOrAllowance: boolean, shouldThrowOnInsufficientBalanceOrAllowance: boolean,
fillTakerTokenAmounts: BigNumber[] = [], fillTakerTokenAmounts: BigNumber[] = [],
) { ): BatchFillOrders {
const batchFill: BatchFillOrders = { const batchFill: BatchFillOrders = {
orderAddresses: [], orderAddresses: [],
orderValues: [], orderValues: [],
@@ -48,7 +48,7 @@ export const formatters = {
signedOrders: SignedOrder[], signedOrders: SignedOrder[],
shouldThrowOnInsufficientBalanceOrAllowance: boolean, shouldThrowOnInsufficientBalanceOrAllowance: boolean,
fillTakerTokenAmount: BigNumber, fillTakerTokenAmount: BigNumber,
) { ): FillOrdersUpTo {
const fillUpTo: FillOrdersUpTo = { const fillUpTo: FillOrdersUpTo = {
orderAddresses: [], orderAddresses: [],
orderValues: [], orderValues: [],
@@ -80,7 +80,7 @@ export const formatters = {
}); });
return fillUpTo; return fillUpTo;
}, },
createBatchCancel(signedOrders: SignedOrder[], cancelTakerTokenAmounts: BigNumber[] = []) { createBatchCancel(signedOrders: SignedOrder[], cancelTakerTokenAmounts: BigNumber[] = []): BatchCancelOrders {
const batchCancel: BatchCancelOrders = { const batchCancel: BatchCancelOrders = {
orderAddresses: [], orderAddresses: [],
orderValues: [], orderValues: [],

View File

@@ -11,7 +11,7 @@ import { TransactionDataParams } from './types';
export class MultiSigWrapper { export class MultiSigWrapper {
private _multiSig: MultiSigWalletContract; private _multiSig: MultiSigWalletContract;
public static encodeFnArgs(name: string, abi: AbiDefinition[], args: any[]) { public static encodeFnArgs(name: string, abi: AbiDefinition[], args: any[]): string {
const abiEntity = _.find(abi, { name }) as MethodAbi; const abiEntity = _.find(abi, { name }) as MethodAbi;
if (_.isUndefined(abiEntity)) { if (_.isUndefined(abiEntity)) {
throw new Error(`Did not find abi entry for name: ${name}`); throw new Error(`Did not find abi entry for name: ${name}`);
@@ -33,7 +33,7 @@ export class MultiSigWrapper {
from: string, from: string,
dataParams: TransactionDataParams, dataParams: TransactionDataParams,
value: BigNumber = new BigNumber(0), value: BigNumber = new BigNumber(0),
) { ): Promise<string> {
const { name, abi, args = [] } = dataParams; const { name, abi, args = [] } = dataParams;
const encoded = MultiSigWrapper.encodeFnArgs(name, abi, args); const encoded = MultiSigWrapper.encodeFnArgs(name, abi, args);
return this._multiSig.submitTransaction.sendTransactionAsync(destination, value, encoded, { return this._multiSig.submitTransaction.sendTransactionAsync(destination, value, encoded, {

View File

@@ -6,6 +6,15 @@ import * as _ from 'lodash';
import { crypto } from './crypto'; import { crypto } from './crypto';
interface OrderAddressesAndValues {
orderAddresses: string[];
orderValues: BigNumber[];
}
interface OrderCancel extends OrderAddressesAndValues {
cancelTakerTokenAmount: BigNumber;
}
export const signedOrderUtils = { export const signedOrderUtils = {
createFill: ( createFill: (
signedOrder: SignedOrder, signedOrder: SignedOrder,
@@ -20,14 +29,14 @@ export const signedOrderUtils = {
}; };
return fill; return fill;
}, },
createCancel(signedOrder: SignedOrder, cancelTakerTokenAmount?: BigNumber) { createCancel(signedOrder: SignedOrder, cancelTakerTokenAmount?: BigNumber): OrderCancel {
const cancel = { const cancel = {
...signedOrderUtils.getOrderAddressesAndValues(signedOrder), ...signedOrderUtils.getOrderAddressesAndValues(signedOrder),
cancelTakerTokenAmount: cancelTakerTokenAmount || signedOrder.takerTokenAmount, cancelTakerTokenAmount: cancelTakerTokenAmount || signedOrder.takerTokenAmount,
}; };
return cancel; return cancel;
}, },
getOrderAddressesAndValues(signedOrder: SignedOrder) { getOrderAddressesAndValues(signedOrder: SignedOrder): OrderAddressesAndValues {
return { return {
orderAddresses: [ orderAddresses: [
signedOrder.maker, signedOrder.maker,

View File

@@ -9,7 +9,7 @@ export class TokenRegWrapper {
constructor(tokenRegContract: TokenRegistryContract) { constructor(tokenRegContract: TokenRegistryContract) {
this._tokenReg = tokenRegContract; this._tokenReg = tokenRegContract;
} }
public async addTokenAsync(token: Token, from: string) { public async addTokenAsync(token: Token, from: string): Promise<string> {
const tx = this._tokenReg.addToken.sendTransactionAsync( const tx = this._tokenReg.addToken.sendTransactionAsync(
token.address as string, token.address as string,
token.name, token.name,
@@ -21,7 +21,7 @@ export class TokenRegWrapper {
); );
return tx; return tx;
} }
public async getTokenMetaDataAsync(tokenAddress: string) { public async getTokenMetaDataAsync(tokenAddress: string): Promise<Token> {
const data = await this._tokenReg.getTokenMetaData.callAsync(tokenAddress); const data = await this._tokenReg.getTokenMetaData.callAsync(tokenAddress);
const token: Token = { const token: Token = {
address: data[0], address: data[0],
@@ -33,7 +33,7 @@ export class TokenRegWrapper {
}; };
return token; return token;
} }
public async getTokenByNameAsync(tokenName: string) { public async getTokenByNameAsync(tokenName: string): Promise<Token> {
const data = await this._tokenReg.getTokenByName.callAsync(tokenName); const data = await this._tokenReg.getTokenByName.callAsync(tokenName);
const token: Token = { const token: Token = {
address: data[0], address: data[0],
@@ -45,7 +45,7 @@ export class TokenRegWrapper {
}; };
return token; return token;
} }
public async getTokenBySymbolAsync(tokenSymbol: string) { public async getTokenBySymbolAsync(tokenSymbol: string): Promise<Token> {
const data = await this._tokenReg.getTokenBySymbol.callAsync(tokenSymbol); const data = await this._tokenReg.getTokenBySymbol.callAsync(tokenSymbol);
const token: Token = { const token: Token = {
address: data[0], address: data[0],

View File

@@ -33,7 +33,7 @@ export class FillScenarios {
this._zrxTokenAddress = zrxTokenAddress; this._zrxTokenAddress = zrxTokenAddress;
this._exchangeContractAddress = exchangeContractAddress; this._exchangeContractAddress = exchangeContractAddress;
} }
public async initTokenBalancesAsync() { public async initTokenBalancesAsync(): Promise<void> {
for (const token of this._tokens) { for (const token of this._tokens) {
if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') { if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
const dummyToken = new DummyTokenContract( const dummyToken = new DummyTokenContract(
@@ -126,7 +126,7 @@ export class FillScenarios {
takerAddress: string, takerAddress: string,
fillableAmount: BigNumber, fillableAmount: BigNumber,
partialFillAmount: BigNumber, partialFillAmount: BigNumber,
) { ): Promise<SignedOrder> {
const [makerAddress] = this._userAddresses; const [makerAddress] = this._userAddresses;
const signedOrder = await this.createAsymmetricFillableSignedOrderAsync( const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
makerTokenAddress, makerTokenAddress,

View File

@@ -23,7 +23,7 @@ export class SchemaValidator {
* instances of that schema. * instances of that schema.
* @param schema The schema to add * @param schema The schema to add
*/ */
public addSchema(schema: Schema) { public addSchema(schema: Schema): void {
this._validator.addSchema(schema, schema.id); this._validator.addSchema(schema, schema.id);
} }
// In order to validate a complex JS object using jsonschema, we must replace any complex // In order to validate a complex JS object using jsonschema, we must replace any complex

View File

@@ -4,7 +4,7 @@ import ChaiBigNumber = require('chai-bignumber');
import * as dirtyChai from 'dirty-chai'; import * as dirtyChai from 'dirty-chai';
export const chaiSetup = { export const chaiSetup = {
configure() { configure(): void {
chai.config.includeStack = true; chai.config.includeStack = true;
chai.use(ChaiBigNumber()); chai.use(ChaiBigNumber());
chai.use(dirtyChai); chai.use(dirtyChai);

View File

@@ -16,7 +16,7 @@ const INVALID_TAKER_FORMAT = 'instance.taker is not of a type(s) string';
* expects values of Solidity type `uint` to be passed as type `BN`. * expects values of Solidity type `uint` to be passed as type `BN`.
* We do not use BN anywhere else in the codebase. * We do not use BN anywhere else in the codebase.
*/ */
function bigNumberToBN(value: BigNumber) { function bigNumberToBN(value: BigNumber): BN {
return new BN(value.toString(), 10); return new BN(value.toString(), 10);
} }

View File

@@ -106,7 +106,7 @@ describe('Signature utils', () => {
}; };
const fakeProvider = { const fakeProvider = {
async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback) { async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> {
if (payload.method === 'eth_sign') { if (payload.method === 'eth_sign') {
const [address, message] = payload.params; const [address, message] = payload.params;
const signature = await web3Wrapper.signMessageAsync(address, message); const signature = await web3Wrapper.signMessageAsync(address, message);
@@ -137,7 +137,7 @@ describe('Signature utils', () => {
s: '0x7feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b', s: '0x7feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b',
}; };
const fakeProvider = { const fakeProvider = {
async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback) { async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> {
if (payload.method === 'eth_sign') { if (payload.method === 'eth_sign') {
const [address, message] = payload.params; const [address, message] = payload.params;
const signature = await web3Wrapper.signMessageAsync(address, message); const signature = await web3Wrapper.signMessageAsync(address, message);

View File

@@ -4,7 +4,7 @@ import ChaiBigNumber = require('chai-bignumber');
import * as dirtyChai from 'dirty-chai'; import * as dirtyChai from 'dirty-chai';
export const chaiSetup = { export const chaiSetup = {
configure() { configure(): void {
chai.config.includeStack = true; chai.config.includeStack = true;
chai.use(ChaiBigNumber()); chai.use(ChaiBigNumber());
chai.use(dirtyChai); chai.use(dirtyChai);

View File

@@ -377,7 +377,7 @@ export class OrderWatcher {
} }
this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress].add(orderHash); this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress].add(orderHash);
} }
private _removeFromDependentOrderHashes(makerAddress: string, tokenAddress: string, orderHash: string) { private _removeFromDependentOrderHashes(makerAddress: string, tokenAddress: string, orderHash: string): void {
this._dependentOrderHashes[makerAddress][tokenAddress].delete(orderHash); this._dependentOrderHashes[makerAddress][tokenAddress].delete(orderHash);
if (this._dependentOrderHashes[makerAddress][tokenAddress].size === 0) { if (this._dependentOrderHashes[makerAddress][tokenAddress].size === 0) {
delete this._dependentOrderHashes[makerAddress][tokenAddress]; delete this._dependentOrderHashes[makerAddress][tokenAddress];

View File

@@ -94,7 +94,7 @@ export class Docs extends React.Component<DocsProps, DocsState> {
docAgnosticFormat: docsInfo.convertToDocAgnosticFormat(v2TypeDocJson), docAgnosticFormat: docsInfo.convertToDocAgnosticFormat(v2TypeDocJson),
}; };
} }
public render() { public render(): React.ReactNode {
const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat) const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
? {} ? {}
: docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat); : docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
@@ -109,14 +109,14 @@ export class Docs extends React.Component<DocsProps, DocsState> {
/> />
); );
} }
private _onVersionSelected(semver: string) { private _onVersionSelected(semver: string): void {
const selectedDocJSON = versionToDocJSON[semver]; const selectedDocJSON = versionToDocJSON[semver];
this.setState({ this.setState({
selectedVersion: semver, selectedVersion: semver,
docAgnosticFormat: docsInfo.convertToDocAgnosticFormat(selectedDocJSON as TypeDocNode), docAgnosticFormat: docsInfo.convertToDocAgnosticFormat(selectedDocJSON as TypeDocNode),
}); });
} }
private _getSourceUrl() { private _getSourceUrl(): string {
const sourceUrl = `${docsInfoConfig.packageUrl}/blob/@0xproject/web3-wrapper@${ const sourceUrl = `${docsInfoConfig.packageUrl}/blob/@0xproject/web3-wrapper@${
this.state.selectedVersion this.state.selectedVersion
}/packages`; }/packages`;

View File

@@ -31,7 +31,7 @@ export class Badge extends React.Component<BadgeProps, BadgeState> {
isHovering: false, isHovering: false,
}; };
} }
public render() { public render(): React.ReactNode {
const badgeStyle = { const badgeStyle = {
...styles.badge, ...styles.badge,
backgroundColor: this.props.backgroundColor, backgroundColor: this.props.backgroundColor,
@@ -48,7 +48,7 @@ export class Badge extends React.Component<BadgeProps, BadgeState> {
</div> </div>
); );
} }
private _setHoverState(isHovering: boolean) { private _setHoverState(isHovering: boolean): void {
this.setState({ this.setState({
isHovering, isHovering,
}); });

View File

@@ -14,7 +14,7 @@ export interface CustomEnumProps {
// This component renders custom string enums that was a work-around for versions of // This component renders custom string enums that was a work-around for versions of
// TypeScript <2.4.0 that did not support them natively. We keep it around to support // TypeScript <2.4.0 that did not support them natively. We keep it around to support
// older versions of 0x.js <0.9.0 // older versions of 0x.js <0.9.0
export function CustomEnum(props: CustomEnumProps) { export const CustomEnum = (props: CustomEnumProps) => {
const type = props.type; const type = props.type;
if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) { if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) {
logUtils.log('We do not yet support `Variable` types that are not strEnums'); logUtils.log('We do not yet support `Variable` types that are not strEnums');
@@ -31,4 +31,4 @@ export function CustomEnum(props: CustomEnumProps) {
{`}`} {`}`}
</span> </span>
); );
} };

View File

@@ -71,19 +71,19 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
isHoveringSidebar: false, isHoveringSidebar: false,
}; };
} }
public componentDidMount() { public componentDidMount(): void {
window.addEventListener('hashchange', this._onHashChanged.bind(this), false); window.addEventListener('hashchange', this._onHashChanged.bind(this), false);
} }
public componentWillUnmount() { public componentWillUnmount(): void {
window.removeEventListener('hashchange', this._onHashChanged.bind(this), false); window.removeEventListener('hashchange', this._onHashChanged.bind(this), false);
} }
public componentDidUpdate(prevProps: DocumentationProps, prevState: DocumentationState) { public componentDidUpdate(prevProps: DocumentationProps, prevState: DocumentationState): void {
if (!_.isEqual(prevProps.docAgnosticFormat, this.props.docAgnosticFormat)) { if (!_.isEqual(prevProps.docAgnosticFormat, this.props.docAgnosticFormat)) {
const hash = window.location.hash.slice(1); const hash = window.location.hash.slice(1);
sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID); sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID);
} }
} }
public render() { public render(): React.ReactNode {
const styles: Styles = { const styles: Styles = {
mainContainers: { mainContainers: {
position: 'absolute', position: 'absolute',
@@ -157,7 +157,7 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
</div> </div>
); );
} }
private _renderLoading(mainContainersStyles: React.CSSProperties) { private _renderLoading(mainContainersStyles: React.CSSProperties): React.ReactNode {
return ( return (
<div className="col col-12" style={mainContainersStyles}> <div className="col col-12" style={mainContainersStyles}>
<div <div
@@ -289,7 +289,7 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
</div> </div>
); );
} }
private _renderNetworkBadgesIfExists(sectionName: string) { private _renderNetworkBadgesIfExists(sectionName: string): React.ReactNode {
if (this.props.docsInfo.type !== SupportedDocJson.Doxity) { if (this.props.docsInfo.type !== SupportedDocJson.Doxity) {
return null; return null;
} }
@@ -368,17 +368,17 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
/> />
); );
} }
private _onSidebarHover(event: React.FormEvent<HTMLInputElement>) { private _onSidebarHover(event: React.FormEvent<HTMLInputElement>): void {
this.setState({ this.setState({
isHoveringSidebar: true, isHoveringSidebar: true,
}); });
} }
private _onSidebarHoverOff() { private _onSidebarHoverOff(): void {
this.setState({ this.setState({
isHoveringSidebar: false, isHoveringSidebar: false,
}); });
} }
private _onHashChanged(event: any) { private _onHashChanged(event: any): void {
const hash = window.location.hash.slice(1); const hash = window.location.hash.slice(1);
sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID); sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID);
} }

View File

@@ -7,7 +7,7 @@ export interface EnumProps {
values: EnumValue[]; values: EnumValue[];
} }
export function Enum(props: EnumProps) { export const Enum = (props: EnumProps) => {
const values = _.map(props.values, (value, i) => { const values = _.map(props.values, (value, i) => {
const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : ''; const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : '';
return `\n\t${value.name}${defaultValueIfAny},`; return `\n\t${value.name}${defaultValueIfAny},`;
@@ -20,4 +20,4 @@ export function Enum(props: EnumProps) {
{`}`} {`}`}
</span> </span>
); );
} };

View File

@@ -24,7 +24,7 @@ export class EventDefinition extends React.Component<EventDefinitionProps, Event
shouldShowAnchor: false, shouldShowAnchor: false,
}; };
} }
public render() { public render(): React.ReactNode {
const event = this.props.event; const event = this.props.event;
const id = `${this.props.sectionName}-${event.name}`; const id = `${this.props.sectionName}-${event.name}`;
return ( return (
@@ -49,7 +49,7 @@ export class EventDefinition extends React.Component<EventDefinitionProps, Event
</div> </div>
); );
} }
private _renderEventCode() { private _renderEventCode(): React.ReactNode {
const indexed = <span style={{ color: colors.green }}> indexed</span>; const indexed = <span style={{ color: colors.green }}> indexed</span>;
const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => { const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => {
const type = ( const type = (
@@ -76,7 +76,7 @@ export class EventDefinition extends React.Component<EventDefinitionProps, Event
</span> </span>
); );
} }
private _setAnchorVisibility(shouldShowAnchor: boolean) { private _setAnchorVisibility(shouldShowAnchor: boolean): void {
this.setState({ this.setState({
shouldShowAnchor, shouldShowAnchor,
}); });

View File

@@ -13,7 +13,7 @@ export interface InterfaceProps {
docsInfo: DocsInfo; docsInfo: DocsInfo;
} }
export function Interface(props: InterfaceProps) { export const Interface = (props: InterfaceProps) => {
const type = props.type; const type = props.type;
const properties = _.map(type.children, property => { const properties = _.map(type.children, property => {
return ( return (
@@ -63,4 +63,4 @@ export function Interface(props: InterfaceProps) {
{`}`} {`}`}
</span> </span>
); );
} };

View File

@@ -88,7 +88,7 @@ function renderParameters(
docsInfo: DocsInfo, docsInfo: DocsInfo,
sectionName: string, sectionName: string,
typeDefinitionByName?: TypeDefinitionByName, typeDefinitionByName?: TypeDefinitionByName,
) { ): React.ReactNode[] {
const params = _.map(parameters, (p: Parameter) => { const params = _.map(parameters, (p: Parameter) => {
const isOptional = p.isOptional; const isOptional = p.isOptional;
const hasDefaultValue = !_.isUndefined(p.defaultValue); const hasDefaultValue = !_.isUndefined(p.defaultValue);
@@ -116,7 +116,7 @@ function renderTypeParameter(
docsInfo: DocsInfo, docsInfo: DocsInfo,
sectionName: string, sectionName: string,
typeDefinitionByName?: TypeDefinitionByName, typeDefinitionByName?: TypeDefinitionByName,
) { ): React.ReactNode {
const typeParam = ( const typeParam = (
<span> <span>
{`<${typeParameter.name} extends `} {`<${typeParameter.name} extends `}

View File

@@ -42,7 +42,7 @@ export class SignatureBlock extends React.Component<SignatureBlockProps, Signatu
shouldShowAnchor: false, shouldShowAnchor: false,
}; };
} }
public render() { public render(): React.ReactNode {
const method = this.props.method; const method = this.props.method;
if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) { if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) {
return null; return null;
@@ -111,14 +111,14 @@ export class SignatureBlock extends React.Component<SignatureBlockProps, Signatu
</div> </div>
); );
} }
private _renderChip(text: string) { private _renderChip(text: string): React.ReactNode {
return ( return (
<div className="p1 mr1" style={styles.chip}> <div className="p1 mr1" style={styles.chip}>
{text} {text}
</div> </div>
); );
} }
private _renderParameterDescriptions(parameters: Parameter[]) { private _renderParameterDescriptions(parameters: Parameter[]): React.ReactNode {
const descriptions = _.map(parameters, parameter => { const descriptions = _.map(parameters, parameter => {
const isOptional = parameter.isOptional; const isOptional = parameter.isOptional;
return ( return (
@@ -146,7 +146,7 @@ export class SignatureBlock extends React.Component<SignatureBlockProps, Signatu
}); });
return descriptions; return descriptions;
} }
private _setAnchorVisibility(shouldShowAnchor: boolean) { private _setAnchorVisibility(shouldShowAnchor: boolean): void {
this.setState({ this.setState({
shouldShowAnchor, shouldShowAnchor,
}); });

View File

@@ -10,7 +10,7 @@ export interface SourceLinkProps {
version: string; version: string;
} }
export function SourceLink(props: SourceLinkProps) { export const SourceLink = (props: SourceLinkProps) => {
const src = props.source; const src = props.source;
const sourceCodeUrl = `${props.sourceUrl}/${src.fileName}#L${src.line}`; const sourceCodeUrl = `${props.sourceUrl}/${src.fileName}#L${src.line}`;
return ( return (
@@ -20,4 +20,4 @@ export function SourceLink(props: SourceLinkProps) {
</a> </a>
</div> </div>
); );
} };

View File

@@ -3,7 +3,7 @@ import * as _ from 'lodash';
import * as React from 'react'; import * as React from 'react';
import { DocsInfo } from '../docs_info'; import { DocsInfo } from '../docs_info';
import { CustomType, CustomTypeChild, KindString, TypeDocTypes } from '../types'; import { CustomType, CustomTypeChild, EnumValue, KindString, TypeDocTypes } from '../types';
import { constants } from '../utils/constants'; import { constants } from '../utils/constants';
import { utils } from '../utils/utils'; import { utils } from '../utils/utils';
@@ -35,7 +35,7 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
shouldShowAnchor: false, shouldShowAnchor: false,
}; };
} }
public render() { public render(): React.ReactNode {
const customType = this.props.customType; const customType = this.props.customType;
if (!this.props.docsInfo.isPublicType(customType.name)) { if (!this.props.docsInfo.isPublicType(customType.name)) {
return null; // no-op return null; // no-op
@@ -129,7 +129,7 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
</div> </div>
); );
} }
private _setAnchorVisibility(shouldShowAnchor: boolean) { private _setAnchorVisibility(shouldShowAnchor: boolean): void {
this.setState({ this.setState({
shouldShowAnchor, shouldShowAnchor,
}); });
@@ -150,7 +150,7 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
* *
* Each property description should be on a new line. * Each property description should be on a new line.
*/ */
private _formatComment(text: string) { private _formatComment(text: string): string {
const NEW_LINE_REGEX = /(\r\n|\n|\r)/gm; const NEW_LINE_REGEX = /(\r\n|\n|\r)/gm;
const sanitizedText = text.replace(NEW_LINE_REGEX, ' '); const sanitizedText = text.replace(NEW_LINE_REGEX, ' ');
const PROPERTY_DESCRIPTION_DIVIDER = ':'; const PROPERTY_DESCRIPTION_DIVIDER = ':';

View File

@@ -11,6 +11,7 @@ import {
DoxityDocObj, DoxityDocObj,
SectionsMap, SectionsMap,
SupportedDocJson, SupportedDocJson,
TypeDefinitionByName,
TypeDocNode, TypeDocNode,
} from './types'; } from './types';
import { doxityUtils } from './utils/doxity_utils'; import { doxityUtils } from './utils/doxity_utils';
@@ -104,13 +105,13 @@ export class DocsInfo {
}); });
return menuSubsectionsBySection; return menuSubsectionsBySection;
} }
public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat) { public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat): { [name: string]: TypeDefinitionByName } {
if (_.isUndefined(this.sections.types)) { if (_.isUndefined(this.sections.types)) {
return {}; return {};
} }
const typeDocSection = docAgnosticFormat[this.sections.types]; const typeDocSection = docAgnosticFormat[this.sections.types];
const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name'); const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name') as any;
return typeDefinitionByName; return typeDefinitionByName;
} }
public isVisibleConstructor(sectionName: string): boolean { public isVisibleConstructor(sectionName: string): boolean {

View File

@@ -142,7 +142,7 @@ export const doxityUtils = {
}; };
return type; return type;
}, },
_isMethod(abiDoc: DoxityAbiDoc) { _isMethod(abiDoc: DoxityAbiDoc): boolean {
if (abiDoc.type !== AbiTypes.Function) { if (abiDoc.type !== AbiTypes.Function) {
return false; return false;
} }
@@ -152,7 +152,7 @@ export const doxityUtils = {
const isMethod = hasNamedOutputIfExists && !isNameAllCaps; const isMethod = hasNamedOutputIfExists && !isNameAllCaps;
return isMethod; return isMethod;
}, },
_isProperty(abiDoc: DoxityAbiDoc) { _isProperty(abiDoc: DoxityAbiDoc): boolean {
if (abiDoc.type !== AbiTypes.Function) { if (abiDoc.type !== AbiTypes.Function) {
return false; return false;
} }

View File

@@ -113,7 +113,7 @@ export const typeDocUtils = {
}); });
return docAgnosticFormat; return docAgnosticFormat;
}, },
_convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string) { _convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string): DocSection {
const docSection: DocSection = { const docSection: DocSection = {
comment: '', comment: '',
constructors: [], constructors: [],

View File

@@ -1,5 +1,5 @@
export const utils = { export const utils = {
spawnSwitchErr(name: string, value: any) { spawnSwitchErr(name: string, value: any): Error {
return new Error(`Unexpected switch value: ${value} encountered for ${name}`); return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
}, },
}; };

View File

@@ -52,7 +52,7 @@ export class AnchorTitle extends React.Component<AnchorTitleProps, AnchorTitleSt
isHovering: false, isHovering: false,
}; };
} }
public render() { public render(): React.ReactNode {
let opacity = 0; let opacity = 0;
if (this.props.shouldShowAnchor) { if (this.props.shouldShowAnchor) {
opacity = this.state.isHovering ? 0.6 : 1; opacity = this.state.isHovering ? 0.6 : 1;
@@ -79,7 +79,7 @@ export class AnchorTitle extends React.Component<AnchorTitleProps, AnchorTitleSt
</div> </div>
); );
} }
private _setHoverState(isHovering: boolean) { private _setHoverState(isHovering: boolean): void {
this.setState({ this.setState({
isHovering, isHovering,
}); });

View File

@@ -12,10 +12,10 @@ export interface MarkdownCodeBlockState {}
export class MarkdownCodeBlock extends React.Component<MarkdownCodeBlockProps, MarkdownCodeBlockState> { export class MarkdownCodeBlock extends React.Component<MarkdownCodeBlockProps, MarkdownCodeBlockState> {
// Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying // Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying
// to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed. // to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed.
public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) { public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState): boolean {
return nextProps.value !== this.props.value || nextProps.language !== this.props.language; return nextProps.value !== this.props.value || nextProps.language !== this.props.language;
} }
public render() { public render(): React.ReactNode {
return ( return (
<span style={{ fontSize: 14 }}> <span style={{ fontSize: 14 }}>
<HighLight className={this.props.language || 'javascript'}>{this.props.value}</HighLight> <HighLight className={this.props.language || 'javascript'}>{this.props.value}</HighLight>

View File

@@ -13,10 +13,10 @@ export interface MarkdownLinkBlockState {}
export class MarkdownLinkBlock extends React.Component<MarkdownLinkBlockProps, MarkdownLinkBlockState> { export class MarkdownLinkBlock extends React.Component<MarkdownLinkBlockProps, MarkdownLinkBlockState> {
// Re-rendering a linkBlock causes it to remain unclickable. // Re-rendering a linkBlock causes it to remain unclickable.
// We therefore noop re-renders on this component if it's props haven't changed. // We therefore noop re-renders on this component if it's props haven't changed.
public shouldComponentUpdate(nextProps: MarkdownLinkBlockProps, nextState: MarkdownLinkBlockState) { public shouldComponentUpdate(nextProps: MarkdownLinkBlockProps, nextState: MarkdownLinkBlockState): boolean {
return nextProps.href !== this.props.href; return nextProps.href !== this.props.href;
} }
public render() { public render(): React.ReactNode {
const href = this.props.href; const href = this.props.href;
const isLinkToSection = _.startsWith(href, '#'); const isLinkToSection = _.startsWith(href, '#');
// If protocol is http or https, we can open in a new tab, otherwise don't for security reasons // If protocol is http or https, we can open in a new tab, otherwise don't for security reasons
@@ -39,7 +39,7 @@ export class MarkdownLinkBlock extends React.Component<MarkdownLinkBlockProps, M
return <a href={href}>{this.props.children}</a>; return <a href={href}>{this.props.children}</a>;
} }
} }
private _onHashUrlClick(href: string) { private _onHashUrlClick(href: string): void {
const hash = href.split('#')[1]; const hash = href.split('#')[1];
utils.scrollToHash(hash, constants.SCROLL_CONTAINER_ID); utils.scrollToHash(hash, constants.SCROLL_CONTAINER_ID);
utils.setUrlHash(hash); utils.setUrlHash(hash);

View File

@@ -39,7 +39,7 @@ export class MarkdownSection extends React.Component<MarkdownSectionProps, Markd
shouldShowAnchor: false, shouldShowAnchor: false,
}; };
} }
public render() { public render(): React.ReactNode {
const { sectionName, markdownContent, headerSize, githubLink } = this.props as PropsWithDefaults; const { sectionName, markdownContent, headerSize, githubLink } = this.props as PropsWithDefaults;
const id = utils.getIdFromName(sectionName); const id = utils.getIdFromName(sectionName);
@@ -87,7 +87,7 @@ export class MarkdownSection extends React.Component<MarkdownSectionProps, Markd
</div> </div>
); );
} }
private _setAnchorVisibility(shouldShowAnchor: boolean) { private _setAnchorVisibility(shouldShowAnchor: boolean): void {
this.setState({ this.setState({
shouldShowAnchor, shouldShowAnchor,
}); });

View File

@@ -43,7 +43,7 @@ export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, N
shouldDisplaySectionHeaders: true, shouldDisplaySectionHeaders: true,
onMenuItemClick: _.noop, onMenuItemClick: _.noop,
}; };
public render() { public render(): React.ReactNode {
const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => { const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => {
const finalSectionName = utils.convertDashesToSpaces(sectionName); const finalSectionName = utils.convertDashesToSpaces(sectionName);
if (this.props.shouldDisplaySectionHeaders) { if (this.props.shouldDisplaySectionHeaders) {

View File

@@ -32,7 +32,7 @@ export class SectionHeader extends React.Component<SectionHeaderProps, SectionHe
shouldShowAnchor: false, shouldShowAnchor: false,
}; };
} }
public render() { public render(): React.ReactNode {
const { sectionName, headerSize } = this.props as PropsWithDefaults; const { sectionName, headerSize } = this.props as PropsWithDefaults;
const finalSectionName = utils.convertDashesToSpaces(this.props.sectionName); const finalSectionName = utils.convertDashesToSpaces(this.props.sectionName);
@@ -65,7 +65,7 @@ export class SectionHeader extends React.Component<SectionHeaderProps, SectionHe
</div> </div>
); );
} }
private _setAnchorVisibility(shouldShowAnchor: boolean) { private _setAnchorVisibility(shouldShowAnchor: boolean): void {
this.setState({ this.setState({
shouldShowAnchor, shouldShowAnchor,
}); });

View File

@@ -14,7 +14,7 @@ export interface VersionDropDownProps {
export interface VersionDropDownState {} export interface VersionDropDownState {}
export class VersionDropDown extends React.Component<VersionDropDownProps, VersionDropDownState> { export class VersionDropDown extends React.Component<VersionDropDownProps, VersionDropDownState> {
public render() { public render(): React.ReactNode {
return ( return (
<div className="mx-auto" style={{ width: 120 }}> <div className="mx-auto" style={{ width: 120 }}>
<DropDownMenu <DropDownMenu
@@ -27,13 +27,13 @@ export class VersionDropDown extends React.Component<VersionDropDownProps, Versi
</div> </div>
); );
} }
private _renderDropDownItems() { private _renderDropDownItems(): React.ReactNode[] {
const items = _.map(this.props.versions, version => { const items = _.map(this.props.versions, version => {
return <MenuItem key={version} value={version} primaryText={`v${version}`} />; return <MenuItem key={version} value={version} primaryText={`v${version}`} />;
}); });
return items; return items;
} }
private _updateSelectedVersion(e: any, index: number, semver: string) { private _updateSelectedVersion(e: any, index: number, semver: string): void {
this.props.onVersionSelected(semver); this.props.onVersionSelected(semver);
} }
} }

View File

@@ -7,7 +7,7 @@ import { EtherscanLinkSuffixes, Networks } from '../types';
import { constants } from './constants'; import { constants } from './constants';
export const utils = { export const utils = {
setUrlHash(anchorId: string) { setUrlHash(anchorId: string): void {
window.location.hash = anchorId; window.location.hash = anchorId;
}, },
scrollToHash(hash: string, containerId: string): void { scrollToHash(hash: string, containerId: string): void {
@@ -26,11 +26,11 @@ export const utils = {
const isUserOnMobile = isMobile(); const isUserOnMobile = isMobile();
return isUserOnMobile; return isUserOnMobile;
}, },
getIdFromName(name: string) { getIdFromName(name: string): string {
const id = name.replace(/ /g, '-'); const id = name.replace(/ /g, '-');
return id; return id;
}, },
convertDashesToSpaces(text: string) { convertDashesToSpaces(text: string): string {
return text.replace(/-/g, ' '); return text.replace(/-/g, ' ');
}, },
getEtherScanLinkIfExists( getEtherScanLinkIfExists(

View File

@@ -11,7 +11,7 @@ import { constants } from './util/constants';
const expect = chai.expect; const expect = chai.expect;
describe('#Compiler', function() { describe('#Compiler', function(): void {
this.timeout(constants.timeoutMs); this.timeout(constants.timeoutMs);
const artifactsDir = `${__dirname}/fixtures/artifacts`; const artifactsDir = `${__dirname}/fixtures/artifacts`;
const contractsDir = `${__dirname}/fixtures/contracts`; const contractsDir = `${__dirname}/fixtures/contracts`;

View File

@@ -51,7 +51,7 @@ export class CoverageSubprovider extends Subprovider {
* @param end Callback to call if subprovider handled the request and wants to pass back the request. * @param end Callback to call if subprovider handled the request and wants to pass back the request.
*/ */
// tslint:disable-next-line:prefer-function-over-method async-suffix // tslint:disable-next-line:prefer-function-over-method async-suffix
public async handleRequest(payload: JSONRPCRequestPayload, next: NextCallback, end: ErrorCallback) { public async handleRequest(payload: JSONRPCRequestPayload, next: NextCallback, end: ErrorCallback): Promise<void> {
switch (payload.method) { switch (payload.method) {
case 'eth_sendTransaction': case 'eth_sendTransaction':
const txData = payload.params[0]; const txData = payload.params[0];

View File

@@ -12,8 +12,22 @@ import { addresses as ropstenAddresses } from './contract_addresses/ropsten_addr
const ENVIRONMENT_NAME = 'SRA Report'; const ENVIRONMENT_NAME = 'SRA Report';
interface EnvironmentValue { export interface EnvironmentValue {
key: string; key: string;
value: string;
enabled: true;
type: 'text';
}
export interface Environment {
name: string;
values: EnvironmentValue[];
}
export interface Addresses {
WETH: string;
ZRX: string;
EXCHANGE: string;
} }
export const postmanEnvironmentFactory = { export const postmanEnvironmentFactory = {
@@ -25,7 +39,7 @@ export const postmanEnvironmentFactory = {
* - Contract addresses based on the network id for making specific queries (ex. baseTokenAddress=ZRX_address) * - Contract addresses based on the network id for making specific queries (ex. baseTokenAddress=ZRX_address)
* - Order properties for making specific queries (ex. maker=orderMaker) * - Order properties for making specific queries (ex. maker=orderMaker)
*/ */
async createPostmanEnvironmentAsync(url: string, networkId: number) { async createPostmanEnvironmentAsync(url: string, networkId: number): Promise<Environment> {
const orderEnvironmentValues = await createOrderEnvironmentValuesAsync(url); const orderEnvironmentValues = await createOrderEnvironmentValuesAsync(url);
const allEnvironmentValues = _.concat( const allEnvironmentValues = _.concat(
createSchemaEnvironmentValues(), createSchemaEnvironmentValues(),
@@ -40,7 +54,7 @@ export const postmanEnvironmentFactory = {
return environment; return environment;
}, },
}; };
function createSchemaEnvironmentValues() { function createSchemaEnvironmentValues(): EnvironmentValue[] {
const schemas: Schema[] = _.values(schemasByName); const schemas: Schema[] = _.values(schemasByName);
const schemaEnvironmentValues = _.compact( const schemaEnvironmentValues = _.compact(
_.map(schemas, (schema: Schema) => { _.map(schemas, (schema: Schema) => {
@@ -60,7 +74,7 @@ function createSchemaEnvironmentValues() {
const result = _.concat(schemaEnvironmentValues, createEnvironmentValue('schemaKeys', JSON.stringify(schemaKeys))); const result = _.concat(schemaEnvironmentValues, createEnvironmentValue('schemaKeys', JSON.stringify(schemaKeys)));
return result; return result;
} }
function createContractAddressEnvironmentValues(networkId: number) { function createContractAddressEnvironmentValues(networkId: number): EnvironmentValue[] {
const contractAddresses = getContractAddresses(networkId); const contractAddresses = getContractAddresses(networkId);
return [ return [
createEnvironmentValue('tokenContractAddress1', contractAddresses.WETH), createEnvironmentValue('tokenContractAddress1', contractAddresses.WETH),
@@ -68,7 +82,7 @@ function createContractAddressEnvironmentValues(networkId: number) {
createEnvironmentValue('exchangeContractAddress', contractAddresses.EXCHANGE), createEnvironmentValue('exchangeContractAddress', contractAddresses.EXCHANGE),
]; ];
} }
async function createOrderEnvironmentValuesAsync(url: string) { async function createOrderEnvironmentValuesAsync(url: string): Promise<EnvironmentValue[]> {
const httpClient = new HttpClient(url); const httpClient = new HttpClient(url);
const orders = await httpClient.getOrdersAsync(); const orders = await httpClient.getOrdersAsync();
const orderIfExists = _.head(orders); const orderIfExists = _.head(orders);
@@ -91,7 +105,7 @@ async function createOrderEnvironmentValuesAsync(url: string) {
]; ];
} }
} }
function getContractAddresses(networkId: number) { function getContractAddresses(networkId: number): Addresses {
switch (networkId) { switch (networkId) {
case 1: case 1:
return mainnetAddresses; return mainnetAddresses;
@@ -105,7 +119,7 @@ function getContractAddresses(networkId: number) {
throw new Error('Unsupported network id'); throw new Error('Unsupported network id');
} }
} }
function convertSchemaIdToKey(schemaId: string) { function convertSchemaIdToKey(schemaId: string): string {
let result = schemaId; let result = schemaId;
if (_.startsWith(result, '/')) { if (_.startsWith(result, '/')) {
result = result.substr(1); result = result.substr(1);
@@ -113,7 +127,8 @@ function convertSchemaIdToKey(schemaId: string) {
result = `${result}Schema`; result = `${result}Schema`;
return result; return result;
} }
function createEnvironmentValue(key: string, value: string) {
function createEnvironmentValue(key: string, value: string): EnvironmentValue {
return { return {
key, key,
value, value,

View File

@@ -3,7 +3,12 @@ import * as chaiAsPromised from 'chai-as-promised';
import * as dirtyChai from 'dirty-chai'; import * as dirtyChai from 'dirty-chai';
import * as _ from 'lodash'; import * as _ from 'lodash';
import 'mocha'; import 'mocha';
import { NewmanRunExecution, NewmanRunExecutionAssertion, NewmanRunSummary } from 'newman'; import {
NewmanRunExecution,
NewmanRunExecutionAssertion,
NewmanRunExecutionAssertionError,
NewmanRunSummary,
} from 'newman';
import * as nock from 'nock'; import * as nock from 'nock';
import * as sraReportCollectionJSON from '../../postman_collections/sra_report.postman_collection.json'; import * as sraReportCollectionJSON from '../../postman_collections/sra_report.postman_collection.json';
@@ -33,7 +38,7 @@ export const testRunner = {
nockInterceptor: nock.Interceptor, nockInterceptor: nock.Interceptor,
postmanCollectionFolderName: string, postmanCollectionFolderName: string,
postmanCollectionRequestName: string, postmanCollectionRequestName: string,
) { ): void {
const newmanRunOptions = { const newmanRunOptions = {
...baseNewmanRunOptions, ...baseNewmanRunOptions,
folder: postmanCollectionFolderName, folder: postmanCollectionFolderName,
@@ -87,7 +92,7 @@ export const testRunner = {
postmanCollectionRequestName: string, postmanCollectionRequestName: string,
malformedJson: object, malformedJson: object,
correctJson: object, correctJson: object,
) { ): void {
const newmanRunOptions = { const newmanRunOptions = {
...baseNewmanRunOptions, ...baseNewmanRunOptions,
folder: postmanCollectionFolderName, folder: postmanCollectionFolderName,
@@ -116,7 +121,7 @@ function findAssertionErrorIfExists(
summary: NewmanRunSummary, summary: NewmanRunSummary,
postmanCollectionRequestName: string, postmanCollectionRequestName: string,
postmanCollectionAssertionName: string, postmanCollectionAssertionName: string,
) { ): NewmanRunExecutionAssertionError | undefined {
const matchingExecutionIfExists = _.find(summary.run.executions, (execution: NewmanRunExecution) => { const matchingExecutionIfExists = _.find(summary.run.executions, (execution: NewmanRunExecution) => {
return execution.item.name === postmanCollectionRequestName; return execution.item.name === postmanCollectionRequestName;
}); });

View File

@@ -8,13 +8,13 @@ import { Callback, ErrorCallback, PartialTxParams, ResponseWithTxParams, WalletS
import { Subprovider } from './subprovider'; import { Subprovider } from './subprovider';
export abstract class BaseWalletSubprovider extends Subprovider { export abstract class BaseWalletSubprovider extends Subprovider {
protected static _validateTxParams(txParams: PartialTxParams) { protected static _validateTxParams(txParams: PartialTxParams): void {
if (!_.isUndefined(txParams.to)) { if (!_.isUndefined(txParams.to)) {
assert.isETHAddressHex('to', txParams.to); assert.isETHAddressHex('to', txParams.to);
} }
assert.isHexString('nonce', txParams.nonce); assert.isHexString('nonce', txParams.nonce);
} }
private static _validateSender(sender: string) { private static _validateSender(sender: string): void {
if (_.isUndefined(sender) || !addressUtils.isAddress(sender)) { if (_.isUndefined(sender) || !addressUtils.isAddress(sender)) {
throw new Error(WalletSubproviderErrors.SenderInvalidOrNotSupplied); throw new Error(WalletSubproviderErrors.SenderInvalidOrNotSupplied);
} }
@@ -33,7 +33,7 @@ export abstract class BaseWalletSubprovider extends Subprovider {
* @param end Callback to call if subprovider handled the request and wants to pass back the request. * @param end Callback to call if subprovider handled the request and wants to pass back the request.
*/ */
// tslint:disable-next-line:async-suffix // tslint:disable-next-line:async-suffix
public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback) { public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback): Promise<void> {
let accounts; let accounts;
let txParams; let txParams;
switch (payload.method) { switch (payload.method) {

View File

@@ -18,7 +18,7 @@ export class EmptyWalletSubprovider extends Subprovider {
* @param end Callback to call if subprovider handled the request and wants to pass back the request. * @param end Callback to call if subprovider handled the request and wants to pass back the request.
*/ */
// tslint:disable-next-line:prefer-function-over-method async-suffix // tslint:disable-next-line:prefer-function-over-method async-suffix
public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback) { public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback): Promise<void> {
switch (payload.method) { switch (payload.method) {
case 'eth_accounts': case 'eth_accounts':
end(null, []); end(null, []);

View File

@@ -32,7 +32,7 @@ export class FakeGasEstimateSubprovider extends Subprovider {
* @param end Callback to call if subprovider handled the request and wants to pass back the request. * @param end Callback to call if subprovider handled the request and wants to pass back the request.
*/ */
// tslint:disable-next-line:prefer-function-over-method async-suffix // tslint:disable-next-line:prefer-function-over-method async-suffix
public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback) { public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback): Promise<void> {
switch (payload.method) { switch (payload.method) {
case 'eth_estimateGas': case 'eth_estimateGas':
end(null, this._constantGasAmount); end(null, this._constantGasAmount);

View File

@@ -28,7 +28,7 @@ export class GanacheSubprovider extends Subprovider {
* @param end Callback to call if subprovider handled the request and wants to pass back the request. * @param end Callback to call if subprovider handled the request and wants to pass back the request.
*/ */
// tslint:disable-next-line:prefer-function-over-method async-suffix // tslint:disable-next-line:prefer-function-over-method async-suffix
public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback) { public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback): Promise<void> {
this._ganacheProvider.sendAsync(payload, (err: Error | null, result: any) => { this._ganacheProvider.sendAsync(payload, (err: Error | null, result: any) => {
end(err, result && result.result); end(err, result && result.result);
}); });

View File

@@ -31,7 +31,7 @@ export class InjectedWeb3Subprovider extends Subprovider {
* @param end Callback to call if subprovider handled the request and wants to pass back the request. * @param end Callback to call if subprovider handled the request and wants to pass back the request.
*/ */
// tslint:disable-next-line:prefer-function-over-method async-suffix // tslint:disable-next-line:prefer-function-over-method async-suffix
public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback) { public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback): Promise<void> {
switch (payload.method) { switch (payload.method) {
case 'web3_clientVersion': case 'web3_clientVersion':
this._injectedWeb3.version.getNode(end); this._injectedWeb3.version.getNode(end);

View File

@@ -74,7 +74,7 @@ export class LedgerSubprovider extends BaseWalletSubprovider {
* Set a desired derivation path when computing the available user addresses * Set a desired derivation path when computing the available user addresses
* @param basDerivationPath The desired derivation path (e.g `44'/60'/0'`) * @param basDerivationPath The desired derivation path (e.g `44'/60'/0'`)
*/ */
public setPath(basDerivationPath: string) { public setPath(basDerivationPath: string): void {
this._baseDerivationPath = basDerivationPath; this._baseDerivationPath = basDerivationPath;
} }
/** /**
@@ -192,7 +192,7 @@ export class LedgerSubprovider extends BaseWalletSubprovider {
this._connectionLock.release(); this._connectionLock.release();
return ledgerEthereumClient; return ledgerEthereumClient;
} }
private async _destroyLedgerClientAsync() { private async _destroyLedgerClientAsync(): Promise<void> {
await this._connectionLock.acquire(); await this._connectionLock.acquire();
if (_.isUndefined(this._ledgerClientIfExists)) { if (_.isUndefined(this._ledgerClientIfExists)) {
this._connectionLock.release(); this._connectionLock.release();

View File

@@ -56,7 +56,7 @@ export class MnemonicWalletSubprovider extends BaseWalletSubprovider {
* Set a desired derivation path when computing the available user addresses * Set a desired derivation path when computing the available user addresses
* @param baseDerivationPath The desired derivation path (e.g `44'/60'/0'`) * @param baseDerivationPath The desired derivation path (e.g `44'/60'/0'`)
*/ */
public setPath(baseDerivationPath: string) { public setPath(baseDerivationPath: string): void {
this._baseDerivationPath = baseDerivationPath; this._baseDerivationPath = baseDerivationPath;
this._derivedKeyInfo = this._initialDerivedKeyInfo(this._baseDerivationPath); this._derivedKeyInfo = this._initialDerivedKeyInfo(this._baseDerivationPath);
} }

View File

@@ -11,7 +11,7 @@ export abstract class Subprovider {
// tslint:disable-next-line:underscore-private-and-protected // tslint:disable-next-line:underscore-private-and-protected
private engine: any; private engine: any;
// Ported from: https://github.com/MetaMask/provider-engine/blob/master/util/random-id.js // Ported from: https://github.com/MetaMask/provider-engine/blob/master/util/random-id.js
private static _getRandomId() { private static _getRandomId(): number {
const extraDigits = 3; const extraDigits = 3;
// 13 time digits // 13 time digits
const datePart = new Date().getTime() * Math.pow(10, extraDigits); const datePart = new Date().getTime() * Math.pow(10, extraDigits);

View File

@@ -3,7 +3,7 @@ import chaiAsPromised = require('chai-as-promised');
import * as dirtyChai from 'dirty-chai'; import * as dirtyChai from 'dirty-chai';
export const chaiSetup = { export const chaiSetup = {
configure() { configure(): void {
chai.config.includeStack = true; chai.config.includeStack = true;
chai.use(dirtyChai); chai.use(dirtyChai);
chai.use(chaiAsPromised); chai.use(chaiAsPromised);

View File

@@ -39,7 +39,7 @@ describe('NonceTrackerSubprovider', () => {
'0x5e1d3a76fbf824220eafc8c79ad578ad2b67d01b0c2425eb1f1347e8f50882ab', '0x5e1d3a76fbf824220eafc8c79ad578ad2b67d01b0c2425eb1f1347e8f50882ab',
'0x5bd428537f05f9830e93792f90ea6a3e2d1ee84952dd96edbae9f658f831ab13', '0x5bd428537f05f9830e93792f90ea6a3e2d1ee84952dd96edbae9f658f831ab13',
]; ];
function createFixtureSubprovider() { function createFixtureSubprovider(): FixtureSubprovider {
let isFirstGetTransactionCount = true; let isFirstGetTransactionCount = true;
const fixedBlockNumberAndTransactionCountProvider = new FixtureSubprovider({ const fixedBlockNumberAndTransactionCountProvider = new FixtureSubprovider({
eth_getBlockByNumber: '0x01', eth_getBlockByNumber: '0x01',

View File

@@ -17,6 +17,7 @@
"dependencies": { "dependencies": {
"0x.js": "^0.37.2", "0x.js": "^0.37.2",
"@0xproject/subproviders": "^0.10.1", "@0xproject/subproviders": "^0.10.1",
"@0xproject/types": "^0.6.3",
"@0xproject/typescript-typings": "^0.3.1", "@0xproject/typescript-typings": "^0.3.1",
"@0xproject/utils": "^0.6.1", "@0xproject/utils": "^0.6.1",
"body-parser": "^1.17.1", "body-parser": "^1.17.1",

View File

@@ -28,12 +28,12 @@ export class DispatchQueue {
public isFull(): boolean { public isFull(): boolean {
return this.size() >= MAX_QUEUE_SIZE; return this.size() >= MAX_QUEUE_SIZE;
} }
public stop() { public stop(): void {
if (!_.isUndefined(this._queueIntervalIdIfExists)) { if (!_.isUndefined(this._queueIntervalIdIfExists)) {
intervalUtils.clearAsyncExcludingInterval(this._queueIntervalIdIfExists); intervalUtils.clearAsyncExcludingInterval(this._queueIntervalIdIfExists);
} }
} }
private _start() { private _start(): void {
this._queueIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval( this._queueIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
async () => { async () => {
const taskAsync = this._queue.shift(); const taskAsync = this._queue.shift();

View File

@@ -11,8 +11,10 @@ const DISPENSE_AMOUNT_TOKEN = 0.1;
const DISPENSE_MAX_AMOUNT_TOKEN = 2; const DISPENSE_MAX_AMOUNT_TOKEN = 2;
const DISPENSE_MAX_AMOUNT_ETHER = 2; const DISPENSE_MAX_AMOUNT_ETHER = 2;
type AsyncTask = () => Promise<void>;
export const dispenseAssetTasks = { export const dispenseAssetTasks = {
dispenseEtherTask(recipientAddress: string, web3: Web3) { dispenseEtherTask(recipientAddress: string, web3: Web3): AsyncTask {
return async () => { return async () => {
logUtils.log(`Processing ETH ${recipientAddress}`); logUtils.log(`Processing ETH ${recipientAddress}`);
const userBalance = await promisify<BigNumber>(web3.eth.getBalance)(recipientAddress); const userBalance = await promisify<BigNumber>(web3.eth.getBalance)(recipientAddress);
@@ -32,7 +34,7 @@ export const dispenseAssetTasks = {
logUtils.log(`Sent ${DISPENSE_AMOUNT_ETHER} ETH to ${recipientAddress} tx: ${txHash}`); logUtils.log(`Sent ${DISPENSE_AMOUNT_ETHER} ETH to ${recipientAddress} tx: ${txHash}`);
}; };
}, },
dispenseTokenTask(recipientAddress: string, tokenSymbol: string, zeroEx: ZeroEx) { dispenseTokenTask(recipientAddress: string, tokenSymbol: string, zeroEx: ZeroEx): AsyncTask {
return async () => { return async () => {
logUtils.log(`Processing ${tokenSymbol} ${recipientAddress}`); logUtils.log(`Processing ${tokenSymbol} ${recipientAddress}`);
const amountToDispense = new BigNumber(DISPENSE_AMOUNT_TOKEN); const amountToDispense = new BigNumber(DISPENSE_AMOUNT_TOKEN);

View File

@@ -5,7 +5,7 @@ import rollbar = require('rollbar');
import { configs } from './configs'; import { configs } from './configs';
export const errorReporter = { export const errorReporter = {
setup() { setup(): void {
rollbar.init(configs.ROLLBAR_ACCESS_KEY, { rollbar.init(configs.ROLLBAR_ACCESS_KEY, {
environment: configs.ENVIRONMENT, environment: configs.ENVIRONMENT,
}); });
@@ -31,7 +31,7 @@ export const errorReporter = {
}); });
}); });
}, },
errorHandler() { errorHandler(): any {
return rollbar.errorHandler(configs.ROLLBAR_ACCESS_KEY); return rollbar.errorHandler(configs.ROLLBAR_ACCESS_KEY);
}, },
}; };

View File

@@ -1,4 +1,5 @@
import { Order, SignedOrder, ZeroEx } from '0x.js'; import { Order, SignedOrder, ZeroEx } from '0x.js';
import { Provider } from '@0xproject/types';
import { BigNumber, logUtils } from '@0xproject/utils'; import { BigNumber, logUtils } from '@0xproject/utils';
import * as express from 'express'; import * as express from 'express';
import * as _ from 'lodash'; import * as _ from 'lodash';
@@ -38,7 +39,7 @@ const FIVE_DAYS_IN_MS = 4.32e8; // TODO: make this configurable
export class Handler { export class Handler {
private _networkConfigByNetworkId: ItemByNetworkId<NetworkConfig> = {}; private _networkConfigByNetworkId: ItemByNetworkId<NetworkConfig> = {};
private static _createProviderEngine(rpcUrl: string) { private static _createProviderEngine(rpcUrl: string): Provider {
if (_.isUndefined(configs.DISPENSER_PRIVATE_KEY)) { if (_.isUndefined(configs.DISPENSER_PRIVATE_KEY)) {
throw new Error('Dispenser Private key not found'); throw new Error('Dispenser Private key not found');
} }
@@ -69,7 +70,7 @@ export class Handler {
}; };
}); });
} }
public getQueueInfo(req: express.Request, res: express.Response) { public getQueueInfo(req: express.Request, res: express.Response): void {
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
const queueInfo = _.mapValues(rpcUrls, (rpcUrl: string, networkId: string) => { const queueInfo = _.mapValues(rpcUrls, (rpcUrl: string, networkId: string) => {
const dispatchQueue = this._networkConfigByNetworkId[networkId].dispatchQueue; const dispatchQueue = this._networkConfigByNetworkId[networkId].dispatchQueue;
@@ -81,19 +82,23 @@ export class Handler {
const payload = JSON.stringify(queueInfo); const payload = JSON.stringify(queueInfo);
res.status(200).send(payload); res.status(200).send(payload);
} }
public dispenseEther(req: express.Request, res: express.Response) { public dispenseEther(req: express.Request, res: express.Response): void {
this._dispenseAsset(req, res, RequestedAssetType.ETH); this._dispenseAsset(req, res, RequestedAssetType.ETH);
} }
public dispenseZRX(req: express.Request, res: express.Response) { public dispenseZRX(req: express.Request, res: express.Response): void {
this._dispenseAsset(req, res, RequestedAssetType.ZRX); this._dispenseAsset(req, res, RequestedAssetType.ZRX);
} }
public async dispenseWETHOrder(req: express.Request, res: express.Response) { public async dispenseWETHOrderAsync(req: express.Request, res: express.Response): Promise<void> {
await this._dispenseOrder(req, res, RequestedAssetType.WETH); await this._dispenseOrderAsync(req, res, RequestedAssetType.WETH);
} }
public async dispenseZRXOrder(req: express.Request, res: express.Response, next: express.NextFunction) { public async dispenseZRXOrderAsync(
await this._dispenseOrder(req, res, RequestedAssetType.ZRX); req: express.Request,
res: express.Response,
next: express.NextFunction,
): Promise<void> {
await this._dispenseOrderAsync(req, res, RequestedAssetType.ZRX);
} }
private _dispenseAsset(req: express.Request, res: express.Response, requestedAssetType: RequestedAssetType) { private _dispenseAsset(req: express.Request, res: express.Response, requestedAssetType: RequestedAssetType): void {
const networkId = req.params.networkId; const networkId = req.params.networkId;
const recipient = req.params.recipient; const recipient = req.params.recipient;
const networkConfig = this._networkConfigByNetworkId[networkId]; const networkConfig = this._networkConfigByNetworkId[networkId];
@@ -121,7 +126,11 @@ export class Handler {
logUtils.log(`Added ${recipient} to queue: ${requestedAssetType} networkId: ${networkId}`); logUtils.log(`Added ${recipient} to queue: ${requestedAssetType} networkId: ${networkId}`);
res.status(200).end(); res.status(200).end();
} }
private async _dispenseOrder(req: express.Request, res: express.Response, requestedAssetType: RequestedAssetType) { private async _dispenseOrderAsync(
req: express.Request,
res: express.Response,
requestedAssetType: RequestedAssetType,
): Promise<void> {
const networkConfig = _.get(this._networkConfigByNetworkId, req.params.networkId); const networkConfig = _.get(this._networkConfigByNetworkId, req.params.networkId);
if (_.isUndefined(networkConfig)) { if (_.isUndefined(networkConfig)) {
res.status(400).send('UNSUPPORTED_NETWORK_ID'); res.status(400).send('UNSUPPORTED_NETWORK_ID');

View File

@@ -8,7 +8,7 @@ import { rpcUrls } from './rpc_urls';
const DEFAULT_NETWORK_ID = 42; // kovan const DEFAULT_NETWORK_ID = 42; // kovan
export const parameterTransformer = { export const parameterTransformer = {
transform(req: Request, res: Response, next: NextFunction) { transform(req: Request, res: Response, next: NextFunction): void {
const recipientAddress = req.params.recipient; const recipientAddress = req.params.recipient;
if (_.isUndefined(recipientAddress) || !addressUtils.isAddress(recipientAddress)) { if (_.isUndefined(recipientAddress) || !addressUtils.isAddress(recipientAddress)) {
res.status(400).send('INVALID_RECIPIENT_ADDRESS'); res.status(400).send('INVALID_RECIPIENT_ADDRESS');

View File

@@ -23,8 +23,8 @@ app.get('/ping', (req: express.Request, res: express.Response) => {
app.get('/info', handler.getQueueInfo.bind(handler)); app.get('/info', handler.getQueueInfo.bind(handler));
app.get('/ether/:recipient', parameterTransformer.transform, handler.dispenseEther.bind(handler)); app.get('/ether/:recipient', parameterTransformer.transform, handler.dispenseEther.bind(handler));
app.get('/zrx/:recipient', parameterTransformer.transform, handler.dispenseZRX.bind(handler)); app.get('/zrx/:recipient', parameterTransformer.transform, handler.dispenseZRX.bind(handler));
app.get('/order/weth/:recipient', parameterTransformer.transform, handler.dispenseWETHOrder.bind(handler)); app.get('/order/weth/:recipient', parameterTransformer.transform, handler.dispenseWETHOrderAsync.bind(handler));
app.get('/order/zrx/:recipient', parameterTransformer.transform, handler.dispenseZRXOrder.bind(handler)); app.get('/order/zrx/:recipient', parameterTransformer.transform, handler.dispenseZRXOrderAsync.bind(handler));
// Log to rollbar any errors unhandled by handlers // Log to rollbar any errors unhandled by handlers
app.use(errorReporter.errorHandler()); app.use(errorReporter.errorHandler());

View File

@@ -50,10 +50,10 @@ function isRelevantClassMember(node: ts.Node): node is RelevantClassMember {
return false; return false;
} }
} }
function nameStartsWithUnderscore(text: string) { function nameStartsWithUnderscore(text: string): boolean {
return text.charCodeAt(0) === UNDERSCORE.charCodeAt(0); return text.charCodeAt(0) === UNDERSCORE.charCodeAt(0);
} }
function memberIsPrivate(node: ts.Declaration) { function memberIsPrivate(node: ts.Declaration): boolean {
return Lint.hasModifier(node.modifiers, ts.SyntaxKind.PrivateKeyword, ts.SyntaxKind.ProtectedKeyword); return Lint.hasModifier(node.modifiers, ts.SyntaxKind.PrivateKeyword, ts.SyntaxKind.ProtectedKeyword);
} }
function nameIsIdentifier(node: ts.Node): node is ts.Identifier { function nameIsIdentifier(node: ts.Node): node is ts.Identifier {

View File

@@ -18,6 +18,7 @@
], ],
"curly": true, "curly": true,
"eofline": true, "eofline": true,
"typedef": [true, "call-signature", "parameter", "property-declaration"],
"encoding": true, "encoding": true,
"import-spacing": true, "import-spacing": true,
"indent": [true, "spaces", 4], "indent": [true, "spaces", 4],

View File

@@ -17,7 +17,7 @@ import { BigNumber } from './configured_bignumber';
export class AbiDecoder { export class AbiDecoder {
private _savedABIs: AbiDefinition[] = []; private _savedABIs: AbiDefinition[] = [];
private _methodIds: { [signatureHash: string]: EventAbi } = {}; private _methodIds: { [signatureHash: string]: EventAbi } = {};
private static _padZeros(address: string) { private static _padZeros(address: string): string {
let formatted = address; let formatted = address;
if (_.startsWith(formatted, '0x')) { if (_.startsWith(formatted, '0x')) {
formatted = formatted.slice(2); formatted = formatted.slice(2);

View File

@@ -1,7 +1,11 @@
import * as _ from 'lodash'; import * as _ from 'lodash';
export const intervalUtils = { export const intervalUtils = {
setAsyncExcludingInterval(fn: () => Promise<void>, intervalMs: number, onError: (err: Error) => void) { setAsyncExcludingInterval(
fn: () => Promise<void>,
intervalMs: number,
onError: (err: Error) => void,
): NodeJS.Timer {
let locked = false; let locked = false;
const intervalId = setInterval(async () => { const intervalId = setInterval(async () => {
if (locked) { if (locked) {
@@ -21,7 +25,7 @@ export const intervalUtils = {
clearAsyncExcludingInterval(intervalId: NodeJS.Timer): void { clearAsyncExcludingInterval(intervalId: NodeJS.Timer): void {
clearInterval(intervalId); clearInterval(intervalId);
}, },
setInterval(fn: () => void, intervalMs: number, onError: (err: Error) => void) { setInterval(fn: () => void, intervalMs: number, onError: (err: Error) => void): NodeJS.Timer {
const intervalId = setInterval(() => { const intervalId = setInterval(() => {
try { try {
fn(); fn();

View File

@@ -117,7 +117,7 @@ export class Web3Wrapper {
* Update the used Web3 provider * Update the used Web3 provider
* @param provider The new Web3 provider to be set * @param provider The new Web3 provider to be set
*/ */
public setProvider(provider: Provider) { public setProvider(provider: Provider): void {
this._web3.setProvider(provider); this._web3.setProvider(provider);
} }
/** /**
@@ -333,7 +333,7 @@ export class Web3Wrapper {
*/ */
public async awaitTransactionMinedAsync( public async awaitTransactionMinedAsync(
txHash: string, txHash: string,
pollingIntervalMs = 1000, pollingIntervalMs: number = 1000,
timeoutMs?: number, timeoutMs?: number,
): Promise<TransactionReceiptWithDecodedLogs> { ): Promise<TransactionReceiptWithDecodedLogs> {
let timeoutExceeded = false; let timeoutExceeded = false;

View File

@@ -4,7 +4,7 @@ import ChaiBigNumber = require('chai-bignumber');
import * as dirtyChai from 'dirty-chai'; import * as dirtyChai from 'dirty-chai';
export const chaiSetup = { export const chaiSetup = {
configure() { configure(): void {
chai.config.includeStack = true; chai.config.includeStack = true;
chai.use(ChaiBigNumber()); chai.use(ChaiBigNumber());
chai.use(dirtyChai); chai.use(dirtyChai);

View File

@@ -39,6 +39,7 @@ import {
BlockchainCallErrs, BlockchainCallErrs,
BlockchainErrs, BlockchainErrs,
ContractInstance, ContractInstance,
Fill,
Order as PortalOrder, Order as PortalOrder,
Providers, Providers,
ProviderType, ProviderType,
@@ -88,7 +89,7 @@ export class Blockchain {
} }
return providerNameIfExists; return providerNameIfExists;
} }
private static async _getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number) { private static async _getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number): Promise<Provider> {
const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3); const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
const publicNodeUrlsIfExistsForNetworkId = configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists]; const publicNodeUrlsIfExistsForNetworkId = configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId); const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId);
@@ -137,7 +138,7 @@ export class Blockchain {
// tslint:disable-next-line:no-floating-promises // tslint:disable-next-line:no-floating-promises
this._onPageLoadInitFireAndForgetAsync(); this._onPageLoadInitFireAndForgetAsync();
} }
public async networkIdUpdatedFireAndForgetAsync(newNetworkId: number) { public async networkIdUpdatedFireAndForgetAsync(newNetworkId: number): Promise<void> {
const isConnected = !_.isUndefined(newNetworkId); const isConnected = !_.isUndefined(newNetworkId);
if (!isConnected) { if (!isConnected) {
this.networkId = newNetworkId; this.networkId = newNetworkId;
@@ -147,17 +148,17 @@ export class Blockchain {
this.networkId = newNetworkId; this.networkId = newNetworkId;
this._dispatcher.encounteredBlockchainError(BlockchainErrs.NoError); this._dispatcher.encounteredBlockchainError(BlockchainErrs.NoError);
await this.fetchTokenInformationAsync(); await this.fetchTokenInformationAsync();
await this._rehydrateStoreWithContractEvents(); await this._rehydrateStoreWithContractEventsAsync();
} }
} }
public async userAddressUpdatedFireAndForgetAsync(newUserAddress: string) { public async userAddressUpdatedFireAndForgetAsync(newUserAddress: string): Promise<void> {
if (this._userAddressIfExists !== newUserAddress) { if (this._userAddressIfExists !== newUserAddress) {
this._userAddressIfExists = newUserAddress; this._userAddressIfExists = newUserAddress;
await this.fetchTokenInformationAsync(); await this.fetchTokenInformationAsync();
await this._rehydrateStoreWithContractEvents(); await this._rehydrateStoreWithContractEventsAsync();
} }
} }
public async nodeVersionUpdatedFireAndForgetAsync(nodeVersion: string) { public async nodeVersionUpdatedFireAndForgetAsync(nodeVersion: string): Promise<void> {
if (this.nodeVersion !== nodeVersion) { if (this.nodeVersion !== nodeVersion) {
this.nodeVersion = nodeVersion; this.nodeVersion = nodeVersion;
} }
@@ -174,13 +175,13 @@ export class Blockchain {
const path = this._ledgerSubprovider.getPath(); const path = this._ledgerSubprovider.getPath();
return path; return path;
} }
public updateLedgerDerivationPathIfExists(path: string) { public updateLedgerDerivationPathIfExists(path: string): void {
if (_.isUndefined(this._ledgerSubprovider)) { if (_.isUndefined(this._ledgerSubprovider)) {
return; // noop return; // noop
} }
this._ledgerSubprovider.setPath(path); this._ledgerSubprovider.setPath(path);
} }
public async updateProviderToLedgerAsync(networkId: number) { public async updateProviderToLedgerAsync(networkId: number): Promise<void> {
utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.'); utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
const isU2FSupported = await utils.isU2FSupportedAsync(); const isU2FSupported = await utils.isU2FSupportedAsync();
@@ -228,7 +229,7 @@ export class Blockchain {
this._blockchainWatcher.startEmittingNetworkConnectionAndUserBalanceState(); this._blockchainWatcher.startEmittingNetworkConnectionAndUserBalanceState();
this._dispatcher.updateProviderType(ProviderType.Ledger); this._dispatcher.updateProviderType(ProviderType.Ledger);
} }
public async updateProviderToInjectedAsync() { public async updateProviderToInjectedAsync(): Promise<void> {
utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.'); utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
if (_.isUndefined(this._cachedProvider)) { if (_.isUndefined(this._cachedProvider)) {
@@ -367,7 +368,7 @@ export class Blockchain {
const unavailableTakerAmount = await this._zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash); const unavailableTakerAmount = await this._zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
return unavailableTakerAmount; return unavailableTakerAmount;
} }
public getExchangeContractAddressIfExists() { public getExchangeContractAddressIfExists(): string | undefined {
return this._zeroEx.exchange.getContractAddress(); return this._zeroEx.exchange.getContractAddress();
} }
public async validateFillOrderThrowIfInvalidAsync( public async validateFillOrderThrowIfInvalidAsync(
@@ -391,7 +392,7 @@ export class Blockchain {
const lowercaseAddress = address.toLowerCase(); const lowercaseAddress = address.toLowerCase();
return Web3Wrapper.isAddress(lowercaseAddress); return Web3Wrapper.isAddress(lowercaseAddress);
} }
public async pollTokenBalanceAsync(token: Token) { public async pollTokenBalanceAsync(token: Token): Promise<BigNumber> {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses); utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
const [currBalance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddressIfExists, token.address); const [currBalance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddressIfExists, token.address);
@@ -445,7 +446,7 @@ export class Blockchain {
this._dispatcher.updateECSignature(ecSignature); this._dispatcher.updateECSignature(ecSignature);
return ecSignature; return ecSignature;
} }
public async mintTestTokensAsync(token: Token) { public async mintTestTokensAsync(token: Token): Promise<void> {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses); utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
const mintableContract = await this._instantiateContractIfExistsAsync(MintableArtifacts, token.address); const mintableContract = await this._instantiateContractIfExistsAsync(MintableArtifacts, token.address);
@@ -489,7 +490,7 @@ export class Blockchain {
); );
await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash); await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
} }
public async doesContractExistAtAddressAsync(address: string) { public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(address); const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(address);
return doesContractExist; return doesContractExist;
} }
@@ -520,7 +521,7 @@ export class Blockchain {
} }
return [balance, allowance]; return [balance, allowance];
} }
public async getUserAccountsAsync() { public async getUserAccountsAsync(): Promise<string[]> {
utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.'); utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
const userAccountsIfExists = await this._zeroEx.getAvailableAddressesAsync(); const userAccountsIfExists = await this._zeroEx.getAvailableAddressesAsync();
return userAccountsIfExists; return userAccountsIfExists;
@@ -528,14 +529,14 @@ export class Blockchain {
// HACK: When a user is using a Ledger, we simply dispatch the selected userAddress, which // HACK: When a user is using a Ledger, we simply dispatch the selected userAddress, which
// by-passes the web3Wrapper logic for updating the prevUserAddress. We therefore need to // by-passes the web3Wrapper logic for updating the prevUserAddress. We therefore need to
// manually update it. This should only be called by the LedgerConfigDialog. // manually update it. This should only be called by the LedgerConfigDialog.
public updateWeb3WrapperPrevUserAddress(newUserAddress: string) { public updateWeb3WrapperPrevUserAddress(newUserAddress: string): void {
this._blockchainWatcher.updatePrevUserAddress(newUserAddress); this._blockchainWatcher.updatePrevUserAddress(newUserAddress);
} }
public destroy() { public destroy(): void {
this._blockchainWatcher.destroy(); this._blockchainWatcher.destroy();
this._stopWatchingExchangeLogFillEvents(); this._stopWatchingExchangeLogFillEvents();
} }
public async fetchTokenInformationAsync() { public async fetchTokenInformationAsync(): Promise<void> {
utils.assert( utils.assert(
!_.isUndefined(this.networkId), !_.isUndefined(this.networkId),
'Cannot call fetchTokenInformationAsync if disconnected from Ethereum node', 'Cannot call fetchTokenInformationAsync if disconnected from Ethereum node',
@@ -624,7 +625,7 @@ export class Blockchain {
private _doesUserAddressExist(): boolean { private _doesUserAddressExist(): boolean {
return !_.isUndefined(this._userAddressIfExists); return !_.isUndefined(this._userAddressIfExists);
} }
private async _rehydrateStoreWithContractEvents() { private async _rehydrateStoreWithContractEventsAsync(): Promise<void> {
// Ensure we are only ever listening to one set of events // Ensure we are only ever listening to one set of events
this._stopWatchingExchangeLogFillEvents(); this._stopWatchingExchangeLogFillEvents();
@@ -675,7 +676,7 @@ export class Blockchain {
}, },
); );
} }
private async _fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues) { private async _fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues): Promise<void> {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses); utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
const fromBlock = tradeHistoryStorage.getFillsLatestBlock(this._userAddressIfExists, this.networkId); const fromBlock = tradeHistoryStorage.getFillsLatestBlock(this._userAddressIfExists, this.networkId);
@@ -697,7 +698,9 @@ export class Blockchain {
tradeHistoryStorage.addFillToUser(this._userAddressIfExists, this.networkId, fill); tradeHistoryStorage.addFillToUser(this._userAddressIfExists, this.networkId, fill);
} }
} }
private async _convertDecodedLogToFillAsync(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) { private async _convertDecodedLogToFillAsync(
decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>,
): Promise<Fill> {
const args = decodedLog.args; const args = decodedLog.args;
const blockTimestamp = await this._web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash); const blockTimestamp = await this._web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash);
const fill = { const fill = {
@@ -716,12 +719,12 @@ export class Blockchain {
}; };
return fill; return fill;
} }
private _doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) { private _doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>): boolean {
const args = decodedLog.args; const args = decodedLog.args;
const isUserMakerOrTaker = args.maker === this._userAddressIfExists || args.taker === this._userAddressIfExists; const isUserMakerOrTaker = args.maker === this._userAddressIfExists || args.taker === this._userAddressIfExists;
return isUserMakerOrTaker; return isUserMakerOrTaker;
} }
private _updateLatestFillsBlockIfNeeded(blockNumber: number) { private _updateLatestFillsBlockIfNeeded(blockNumber: number): void {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses); utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
const isBlockPending = _.isNull(blockNumber); const isBlockPending = _.isNull(blockNumber);
@@ -762,7 +765,7 @@ export class Blockchain {
}); });
return tokenByAddress; return tokenByAddress;
} }
private async _onPageLoadInitFireAndForgetAsync() { private async _onPageLoadInitFireAndForgetAsync(): Promise<void> {
await utils.onPageLoadAsync(); // wait for page to load await utils.onPageLoadAsync(); // wait for page to load
// Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in // Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in
@@ -805,9 +808,9 @@ export class Blockchain {
this._dispatcher.updateUserAddress(this._userAddressIfExists); this._dispatcher.updateUserAddress(this._userAddressIfExists);
await this.fetchTokenInformationAsync(); await this.fetchTokenInformationAsync();
this._blockchainWatcher.startEmittingNetworkConnectionAndUserBalanceState(); this._blockchainWatcher.startEmittingNetworkConnectionAndUserBalanceState();
await this._rehydrateStoreWithContractEvents(); await this._rehydrateStoreWithContractEventsAsync();
} }
private _updateProviderName(injectedWeb3: Web3) { private _updateProviderName(injectedWeb3: Web3): void {
const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3); const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
const providerName = doesInjectedWeb3Exist const providerName = doesInjectedWeb3Exist
? Blockchain._getNameGivenProvider(injectedWeb3.currentProvider) ? Blockchain._getNameGivenProvider(injectedWeb3.currentProvider)
@@ -849,12 +852,12 @@ export class Blockchain {
} }
} }
} }
private _showFlashMessageIfLedger() { private _showFlashMessageIfLedger(): void {
if (!_.isUndefined(this._ledgerSubprovider)) { if (!_.isUndefined(this._ledgerSubprovider)) {
this._dispatcher.showFlashMessage('Confirm the transaction on your Ledger Nano S'); this._dispatcher.showFlashMessage('Confirm the transaction on your Ledger Nano S');
} }
} }
private async _updateDefaultGasPriceAsync() { private async _updateDefaultGasPriceAsync(): Promise<void> {
try { try {
const gasInfo = await backendClient.getGasInfoAsync(); const gasInfo = await backendClient.getGasInfoAsync();
const gasPriceInGwei = new BigNumber(gasInfo.average / 10); const gasPriceInGwei = new BigNumber(gasInfo.average / 10);

View File

@@ -23,8 +23,8 @@ export class BlockchainWatcher {
this._shouldPollUserAddress = shouldPollUserAddress; this._shouldPollUserAddress = shouldPollUserAddress;
this._web3Wrapper = web3Wrapper; this._web3Wrapper = web3Wrapper;
} }
public destroy() { public destroy(): void {
this._stopEmittingNetworkConnectionAndUserBalanceStateAsync(); this._stopEmittingNetworkConnectionAndUserBalanceState();
// HACK: stop() is only available on providerEngine instances // HACK: stop() is only available on providerEngine instances
const provider = this._web3Wrapper.getProvider(); const provider = this._web3Wrapper.getProvider();
if (!_.isUndefined((provider as any).stop)) { if (!_.isUndefined((provider as any).stop)) {
@@ -32,10 +32,10 @@ export class BlockchainWatcher {
} }
} }
// This should only be called from the LedgerConfigDialog // This should only be called from the LedgerConfigDialog
public updatePrevUserAddress(userAddress: string) { public updatePrevUserAddress(userAddress: string): void {
this._prevUserAddressIfExists = userAddress; this._prevUserAddressIfExists = userAddress;
} }
public startEmittingNetworkConnectionAndUserBalanceState() { public startEmittingNetworkConnectionAndUserBalanceState(): void {
if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) { if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) {
return; // we are already emitting the state return; // we are already emitting the state
} }
@@ -88,18 +88,18 @@ export class BlockchainWatcher {
5000, 5000,
(err: Error) => { (err: Error) => {
logUtils.log(`Watching network and balances failed: ${err.stack}`); logUtils.log(`Watching network and balances failed: ${err.stack}`);
this._stopEmittingNetworkConnectionAndUserBalanceStateAsync(); this._stopEmittingNetworkConnectionAndUserBalanceState();
}, },
); );
} }
private async _updateUserWeiBalanceAsync(userAddress: string) { private async _updateUserWeiBalanceAsync(userAddress: string): Promise<void> {
const balanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(userAddress); const balanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(userAddress);
if (!balanceInWei.eq(this._prevUserEtherBalanceInWei)) { if (!balanceInWei.eq(this._prevUserEtherBalanceInWei)) {
this._prevUserEtherBalanceInWei = balanceInWei; this._prevUserEtherBalanceInWei = balanceInWei;
this._dispatcher.updateUserWeiBalance(balanceInWei); this._dispatcher.updateUserWeiBalance(balanceInWei);
} }
} }
private _stopEmittingNetworkConnectionAndUserBalanceStateAsync() { private _stopEmittingNetworkConnectionAndUserBalanceState(): void {
if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) { if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) {
intervalUtils.clearAsyncExcludingInterval(this._watchNetworkAndBalanceIntervalId); intervalUtils.clearAsyncExcludingInterval(this._watchNetworkAndBalanceIntervalId);
} }

View File

@@ -18,7 +18,7 @@ interface BlockchainErrDialogProps {
} }
export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProps, undefined> { export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProps, undefined> {
public render() { public render(): React.ReactNode {
const dialogActions = [ const dialogActions = [
<FlatButton <FlatButton
key="blockchainErrOk" key="blockchainErrOk"
@@ -45,7 +45,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
</Dialog> </Dialog>
); );
} }
private _getTitle(hasWalletAddress: boolean) { private _getTitle(hasWalletAddress: boolean): string {
if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) { if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
return '0x smart contracts not found'; return '0x smart contracts not found';
} else if (!hasWalletAddress) { } else if (!hasWalletAddress) {
@@ -58,7 +58,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
return 'Unexpected error'; return 'Unexpected error';
} }
} }
private _renderExplanation(hasWalletAddress: boolean) { private _renderExplanation(hasWalletAddress: boolean): React.ReactNode {
if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) { if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
return this._renderContractsNotDeployedExplanation(); return this._renderContractsNotDeployedExplanation();
} else if (!hasWalletAddress) { } else if (!hasWalletAddress) {
@@ -71,7 +71,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
return this._renderUnexpectedErrorExplanation(); return this._renderUnexpectedErrorExplanation();
} }
} }
private _renderDisconnectedFromNode() { private _renderDisconnectedFromNode(): React.ReactNode {
return ( return (
<div> <div>
You were disconnected from the backing Ethereum node. If using{' '} You were disconnected from the backing Ethereum node. If using{' '}
@@ -86,7 +86,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
</div> </div>
); );
} }
private _renderDefaultTokenNotInTokenRegistry() { private _renderDefaultTokenNotInTokenRegistry(): React.ReactNode {
return ( return (
<div> <div>
The TokenRegistry deployed on your network does not contain the needed default tokens for 0x Portal to The TokenRegistry deployed on your network does not contain the needed default tokens for 0x Portal to
@@ -96,10 +96,10 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
</div> </div>
); );
} }
private _renderUnexpectedErrorExplanation() { private _renderUnexpectedErrorExplanation(): React.ReactNode {
return <div>We encountered an unexpected error. Please try refreshing the page.</div>; return <div>We encountered an unexpected error. Please try refreshing the page.</div>;
} }
private _renderNoWalletFoundExplanation() { private _renderNoWalletFoundExplanation(): React.ReactNode {
return ( return (
<div> <div>
<div> <div>
@@ -137,7 +137,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
</div> </div>
); );
} }
private _renderContractsNotDeployedExplanation() { private _renderContractsNotDeployedExplanation(): React.ReactNode {
return ( return (
<div> <div>
<div> <div>

View File

@@ -47,14 +47,14 @@ export class EthWethConversionDialog extends React.Component<
ethTokenBalance: new BigNumber(0), ethTokenBalance: new BigNumber(0),
}; };
} }
public componentWillMount() { public componentWillMount(): void {
// tslint:disable-next-line:no-floating-promises // tslint:disable-next-line:no-floating-promises
this._fetchEthTokenBalanceAsync(); this._fetchEthTokenBalanceAsync();
} }
public componentWillUnmount() { public componentWillUnmount(): void {
this._isUnmounted = true; this._isUnmounted = true;
} }
public render() { public render(): React.ReactNode {
const convertDialogActions = [ const convertDialogActions = [
<FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />, <FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
<FlatButton key="convert" label="Convert" primary={true} onTouchTap={this._onConvertClick.bind(this)} />, <FlatButton key="convert" label="Convert" primary={true} onTouchTap={this._onConvertClick.bind(this)} />,
@@ -72,7 +72,7 @@ export class EthWethConversionDialog extends React.Component<
</Dialog> </Dialog>
); );
} }
private _renderConversionDialogBody() { private _renderConversionDialogBody(): React.ReactNode {
const explanation = const explanation =
this.props.direction === Side.Deposit this.props.direction === Side.Deposit
? 'Convert your Ether into a tokenized, tradable form.' ? 'Convert your Ether into a tokenized, tradable form.'
@@ -137,7 +137,7 @@ export class EthWethConversionDialog extends React.Component<
</div> </div>
); );
} }
private _renderCurrency(isWrappedVersion: boolean) { private _renderCurrency(isWrappedVersion: boolean): React.ReactNode {
const name = isWrappedVersion ? 'Wrapped Ether' : 'Ether'; const name = isWrappedVersion ? 'Wrapped Ether' : 'Ether';
const iconUrl = isWrappedVersion ? '/images/token_icons/ether_erc20.png' : '/images/ether.png'; const iconUrl = isWrappedVersion ? '/images/token_icons/ether_erc20.png' : '/images/ether.png';
const symbol = isWrappedVersion ? 'WETH' : 'ETH'; const symbol = isWrappedVersion ? 'WETH' : 'ETH';
@@ -155,18 +155,18 @@ export class EthWethConversionDialog extends React.Component<
</div> </div>
); );
} }
private _onMaxClick() { private _onMaxClick(): void {
this.setState({ this.setState({
value: this.state.ethTokenBalance, value: this.state.ethTokenBalance,
}); });
} }
private _onValueChange(isValid: boolean, amount?: BigNumber) { private _onValueChange(isValid: boolean, amount?: BigNumber): void {
this.setState({ this.setState({
value: amount, value: amount,
hasErrors: !isValid, hasErrors: !isValid,
}); });
} }
private _onConvertClick() { private _onConvertClick(): void {
if (this.state.hasErrors) { if (this.state.hasErrors) {
this.setState({ this.setState({
shouldShowIncompleteErrs: true, shouldShowIncompleteErrs: true,
@@ -179,13 +179,13 @@ export class EthWethConversionDialog extends React.Component<
this.props.onComplete(this.props.direction, value); this.props.onComplete(this.props.direction, value);
} }
} }
private _onCancel() { private _onCancel(): void {
this.setState({ this.setState({
value: undefined, value: undefined,
}); });
this.props.onCancelled(); this.props.onCancelled();
} }
private async _fetchEthTokenBalanceAsync() { private async _fetchEthTokenBalanceAsync(): Promise<void> {
const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress; const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress;
const [balance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync( const [balance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
userAddressIfExists, userAddressIfExists,

View File

@@ -59,7 +59,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
preferredNetworkId: props.networkId, preferredNetworkId: props.networkId,
}; };
} }
public render() { public render(): React.ReactNode {
const dialogActions = [ const dialogActions = [
<FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={this._onClose.bind(this)} />, <FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={this._onClose.bind(this)} />,
]; ];
@@ -82,7 +82,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
</Dialog> </Dialog>
); );
} }
private _renderConnectStep() { private _renderConnectStep(): React.ReactNode {
const networkIds = _.values(sharedConstants.NETWORK_ID_BY_NAME); const networkIds = _.values(sharedConstants.NETWORK_ID_BY_NAME);
return ( return (
<div> <div>
@@ -122,7 +122,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
</div> </div>
); );
} }
private _renderSelectAddressStep() { private _renderSelectAddressStep(): React.ReactNode {
return ( return (
<div> <div>
<div> <div>
@@ -159,7 +159,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
</div> </div>
); );
} }
private _renderAddressTableRows() { private _renderAddressTableRows(): React.ReactNode {
const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => { const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => {
const balanceInWei = this.state.addressBalances[i]; const balanceInWei = this.state.addressBalances[i];
const addressTooltipId = `address-${userAddress}`; const addressTooltipId = `address-${userAddress}`;
@@ -189,7 +189,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
}); });
return rows; return rows;
} }
private _onClose() { private _onClose(): void {
this.setState({ this.setState({
connectionErrMsg: '', connectionErrMsg: '',
stepIndex: LedgerSteps.CONNECT, stepIndex: LedgerSteps.CONNECT,
@@ -197,7 +197,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
const isOpen = false; const isOpen = false;
this.props.toggleDialogFn(isOpen); this.props.toggleDialogFn(isOpen);
} }
private _onAddressSelected(selectedRowIndexes: number[]) { private _onAddressSelected(selectedRowIndexes: number[]): void {
const selectedRowIndex = selectedRowIndexes[0]; const selectedRowIndex = selectedRowIndexes[0];
const selectedAddress = this.state.userAddresses[selectedRowIndex]; const selectedAddress = this.state.userAddresses[selectedRowIndex];
const selectAddressBalance = this.state.addressBalances[selectedRowIndex]; const selectAddressBalance = this.state.addressBalances[selectedRowIndex];
@@ -228,7 +228,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
} }
return didSucceed; return didSucceed;
} }
private async _fetchAddressesAndBalancesAsync() { private async _fetchAddressesAndBalancesAsync(): Promise<boolean> {
let userAddresses: string[]; let userAddresses: string[];
const addressBalances: BigNumber[] = []; const addressBalances: BigNumber[] = [];
try { try {
@@ -250,7 +250,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
}); });
return true; return true;
} }
private _onDerivationPathChanged(e: any, derivationPath: string) { private _onDerivationPathChanged(e: any, derivationPath: string): void {
let derivationErrMsg = ''; let derivationErrMsg = '';
if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) { if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) {
derivationErrMsg = 'Must be valid Ethereum path.'; derivationErrMsg = 'Must be valid Ethereum path.';
@@ -261,7 +261,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
derivationErrMsg, derivationErrMsg,
}); });
} }
private async _onConnectLedgerClickAsync() { private async _onConnectLedgerClickAsync(): Promise<boolean> {
const isU2FSupported = await utils.isU2FSupportedAsync(); const isU2FSupported = await utils.isU2FSupportedAsync();
if (!isU2FSupported) { if (!isU2FSupported) {
logUtils.log(`U2F not supported in this browser`); logUtils.log(`U2F not supported in this browser`);
@@ -295,7 +295,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
} }
return userAddresses; return userAddresses;
} }
private _onSelectedNetworkUpdated(e: any, index: number, networkId: number) { private _onSelectedNetworkUpdated(e: any, index: number, networkId: number): void {
this.setState({ this.setState({
preferredNetworkId: networkId, preferredNetworkId: networkId,
}); });

View File

@@ -8,7 +8,7 @@ interface PortalDisclaimerDialogProps {
onToggleDialog: () => void; onToggleDialog: () => void;
} }
export function PortalDisclaimerDialog(props: PortalDisclaimerDialogProps) { export const PortalDisclaimerDialog = (props: PortalDisclaimerDialogProps) => {
return ( return (
<Dialog <Dialog
title="0x Portal Disclaimer" title="0x Portal Disclaimer"
@@ -33,4 +33,4 @@ export function PortalDisclaimerDialog(props: PortalDisclaimerDialogProps) {
</div> </div>
</Dialog> </Dialog>
); );
} };

View File

@@ -35,7 +35,7 @@ export class SendDialog extends React.Component<SendDialogProps, SendDialogState
isAmountValid: false, isAmountValid: false,
}; };
} }
public render() { public render(): React.ReactNode {
const transferDialogActions = [ const transferDialogActions = [
<FlatButton key="cancelTransfer" label="Cancel" onTouchTap={this._onCancel.bind(this)} />, <FlatButton key="cancelTransfer" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
<FlatButton <FlatButton
@@ -57,7 +57,7 @@ export class SendDialog extends React.Component<SendDialogProps, SendDialogState
</Dialog> </Dialog>
); );
} }
private _renderSendDialogBody() { private _renderSendDialogBody(): React.ReactNode {
return ( return (
<div className="mx-auto" style={{ maxWidth: 300 }}> <div className="mx-auto" style={{ maxWidth: 300 }}>
<div style={{ height: 80 }}> <div style={{ height: 80 }}>
@@ -86,19 +86,19 @@ export class SendDialog extends React.Component<SendDialogProps, SendDialogState
</div> </div>
); );
} }
private _onRecipientChange(recipient?: string) { private _onRecipientChange(recipient?: string): void {
this.setState({ this.setState({
shouldShowIncompleteErrs: false, shouldShowIncompleteErrs: false,
recipient, recipient,
}); });
} }
private _onValueChange(isValid: boolean, amount?: BigNumber) { private _onValueChange(isValid: boolean, amount?: BigNumber): void {
this.setState({ this.setState({
isAmountValid: isValid, isAmountValid: isValid,
value: amount, value: amount,
}); });
} }
private _onSendClick() { private _onSendClick(): void {
if (this._hasErrors()) { if (this._hasErrors()) {
this.setState({ this.setState({
shouldShowIncompleteErrs: true, shouldShowIncompleteErrs: true,
@@ -112,13 +112,13 @@ export class SendDialog extends React.Component<SendDialogProps, SendDialogState
this.props.onComplete(this.state.recipient, value); this.props.onComplete(this.state.recipient, value);
} }
} }
private _onCancel() { private _onCancel(): void {
this.setState({ this.setState({
value: undefined, value: undefined,
}); });
this.props.onCancelled(); this.props.onCancelled();
} }
private _hasErrors() { private _hasErrors(): boolean {
return _.isUndefined(this.state.recipient) || _.isUndefined(this.state.value) || !this.state.isAmountValid; return _.isUndefined(this.state.recipient) || _.isUndefined(this.state.value) || !this.state.isAmountValid;
} }
} }

View File

@@ -33,7 +33,7 @@ export class TrackTokenConfirmationDialog extends React.Component<
isAddingTokenToTracked: false, isAddingTokenToTracked: false,
}; };
} }
public render() { public render(): React.ReactNode {
const tokens = this.props.tokens; const tokens = this.props.tokens;
return ( return (
<Dialog <Dialog
@@ -66,7 +66,7 @@ export class TrackTokenConfirmationDialog extends React.Component<
</Dialog> </Dialog>
); );
} }
private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) { private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean): Promise<void> {
if (!didUserAcceptTracking) { if (!didUserAcceptTracking) {
this.props.onToggleDialog(didUserAcceptTracking); this.props.onToggleDialog(didUserAcceptTracking);
return; return;

View File

@@ -9,7 +9,7 @@ interface U2fNotSupportedDialogProps {
onToggleDialog: () => void; onToggleDialog: () => void;
} }
export function U2fNotSupportedDialog(props: U2fNotSupportedDialogProps) { export const U2fNotSupportedDialog = (props: U2fNotSupportedDialogProps) => {
return ( return (
<Dialog <Dialog
title="U2F Not Supported" title="U2F Not Supported"
@@ -43,4 +43,4 @@ export function U2fNotSupportedDialog(props: U2fNotSupportedDialogProps) {
</div> </div>
</Dialog> </Dialog>
); );
} };

View File

@@ -8,7 +8,7 @@ interface WrappedEthSectionNoticeDialogProps {
onToggleDialog: () => void; onToggleDialog: () => void;
} }
export function WrappedEthSectionNoticeDialog(props: WrappedEthSectionNoticeDialogProps) { export const WrappedEthSectionNoticeDialog = (props: WrappedEthSectionNoticeDialogProps) => {
return ( return (
<Dialog <Dialog
title="Dedicated Wrapped Ether Section" title="Dedicated Wrapped Ether Section"
@@ -30,4 +30,4 @@ export function WrappedEthSectionNoticeDialog(props: WrappedEthSectionNoticeDial
</div> </div>
</Dialog> </Dialog>
); );
} };

View File

@@ -13,7 +13,7 @@ interface NetworkDropDownProps {
interface NetworkDropDownState {} interface NetworkDropDownState {}
export class NetworkDropDown extends React.Component<NetworkDropDownProps, NetworkDropDownState> { export class NetworkDropDown extends React.Component<NetworkDropDownProps, NetworkDropDownState> {
public render() { public render(): React.ReactNode {
return ( return (
<div className="mx-auto" style={{ width: 120 }}> <div className="mx-auto" style={{ width: 120 }}>
<DropDownMenu value={this.props.selectedNetworkId} onChange={this.props.updateSelectedNetwork}> <DropDownMenu value={this.props.selectedNetworkId} onChange={this.props.updateSelectedNetwork}>
@@ -22,7 +22,7 @@ export class NetworkDropDown extends React.Component<NetworkDropDownProps, Netwo
</div> </div>
); );
} }
private _renderDropDownItems() { private _renderDropDownItems(): React.ReactNode {
const items = _.map(this.props.avialableNetworkIds, networkId => { const items = _.map(this.props.avialableNetworkIds, networkId => {
const networkName = sharedConstants.NETWORK_NAME_BY_ID[networkId]; const networkName = sharedConstants.NETWORK_NAME_BY_ID[networkId];
const primaryText = ( const primaryText = (

View File

@@ -46,7 +46,7 @@ export class EthWethConversionButton extends React.Component<
isEthConversionHappening: false, isEthConversionHappening: false,
}; };
} }
public render() { public render(): React.ReactNode {
const labelStyle = this.state.isEthConversionHappening ? { fontSize: 10 } : {}; const labelStyle = this.state.isEthConversionHappening ? { fontSize: 10 } : {};
let callToActionLabel; let callToActionLabel;
let inProgressLabel; let inProgressLabel;
@@ -81,12 +81,12 @@ export class EthWethConversionButton extends React.Component<
</div> </div>
); );
} }
private _toggleConversionDialog() { private _toggleConversionDialog(): void {
this.setState({ this.setState({
isEthConversionDialogVisible: !this.state.isEthConversionDialogVisible, isEthConversionDialogVisible: !this.state.isEthConversionDialogVisible,
}); });
} }
private async _onConversionAmountSelectedAsync(direction: Side, value: BigNumber) { private async _onConversionAmountSelectedAsync(direction: Side, value: BigNumber): Promise<void> {
this.setState({ this.setState({
isEthConversionHappening: true, isEthConversionHappening: true,
}); });

View File

@@ -65,7 +65,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
}, },
}; };
} }
public componentWillReceiveProps(nextProps: EthWrappersProps) { public componentWillReceiveProps(nextProps: EthWrappersProps): void {
if ( if (
nextProps.userAddress !== this.props.userAddress || nextProps.userAddress !== this.props.userAddress ||
nextProps.networkId !== this.props.networkId || nextProps.networkId !== this.props.networkId ||
@@ -75,15 +75,15 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
this._fetchWETHStateAsync(); this._fetchWETHStateAsync();
} }
} }
public componentDidMount() { public componentDidMount(): void {
window.scrollTo(0, 0); window.scrollTo(0, 0);
// tslint:disable-next-line:no-floating-promises // tslint:disable-next-line:no-floating-promises
this._fetchWETHStateAsync(); this._fetchWETHStateAsync();
} }
public componentWillUnmount() { public componentWillUnmount(): void {
this._isUnmounted = true; this._isUnmounted = true;
} }
public render() { public render(): React.ReactNode {
const etherToken = this._getEthToken(); const etherToken = this._getEthToken();
const wethBalance = ZeroEx.toUnitAmount(this.state.ethTokenState.balance, constants.DECIMAL_PLACES_ETH); const wethBalance = ZeroEx.toUnitAmount(this.state.ethTokenState.balance, constants.DECIMAL_PLACES_ETH);
const isBidirectional = true; const isBidirectional = true;
@@ -222,7 +222,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
</div> </div>
); );
} }
private _renderActionColumnTitle(isBidirectional: boolean) { private _renderActionColumnTitle(isBidirectional: boolean): React.ReactNode {
let iconClass = 'zmdi-long-arrow-right'; let iconClass = 'zmdi-long-arrow-right';
let leftSymbol = 'WETH'; let leftSymbol = 'WETH';
let rightSymbol = 'ETH'; let rightSymbol = 'ETH';
@@ -241,7 +241,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
</div> </div>
); );
} }
private _renderOutdatedWeths(etherToken: Token, etherTokenState: TokenState) { private _renderOutdatedWeths(etherToken: Token, etherTokenState: TokenState): React.ReactNode {
const rows = _.map( const rows = _.map(
configs.OUTDATED_WRAPPED_ETHERS, configs.OUTDATED_WRAPPED_ETHERS,
(outdatedWETHByNetworkId: OutdatedWrappedEtherByNetworkId) => { (outdatedWETHByNetworkId: OutdatedWrappedEtherByNetworkId) => {
@@ -313,7 +313,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
); );
return rows; return rows;
} }
private _renderTokenLink(tokenLabel: React.ReactNode, etherscanUrl: string) { private _renderTokenLink(tokenLabel: React.ReactNode, etherscanUrl: string): React.ReactNode {
return ( return (
<span> <span>
{_.isUndefined(etherscanUrl) ? ( {_.isUndefined(etherscanUrl) ? (
@@ -326,7 +326,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
</span> </span>
); );
} }
private _renderToken(name: string, address: string, imgPath: string) { private _renderToken(name: string, address: string, imgPath: string): React.ReactNode {
const tooltipId = `tooltip-${address}`; const tooltipId = `tooltip-${address}`;
return ( return (
<div className="flex"> <div className="flex">
@@ -340,7 +340,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
</div> </div>
); );
} }
private async _onOutdatedConversionSuccessfulAsync(outdatedWETHAddress: string) { private async _onOutdatedConversionSuccessfulAsync(outdatedWETHAddress: string): Promise<void> {
const currentOutdatedWETHState = this.state.outdatedWETHStateByAddress[outdatedWETHAddress]; const currentOutdatedWETHState = this.state.outdatedWETHStateByAddress[outdatedWETHAddress];
this.setState({ this.setState({
outdatedWETHStateByAddress: { outdatedWETHStateByAddress: {
@@ -368,7 +368,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
}, },
}); });
} }
private async _fetchWETHStateAsync() { private async _fetchWETHStateAsync(): Promise<void> {
const tokens = _.values(this.props.tokenByAddress); const tokens = _.values(this.props.tokenByAddress);
const wethToken = _.find(tokens, token => token.symbol === 'WETH'); const wethToken = _.find(tokens, token => token.symbol === 'WETH');
const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress; const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress;
@@ -414,12 +414,12 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
); );
return outdatedWETHAddresses; return outdatedWETHAddresses;
} }
private _getEthToken() { private _getEthToken(): Token {
const tokens = _.values(this.props.tokenByAddress); const tokens = _.values(this.props.tokenByAddress);
const etherToken = _.find(tokens, { symbol: 'WETH' }); const etherToken = _.find(tokens, { symbol: 'WETH' });
return etherToken; return etherToken;
} }
private async _refetchEthTokenStateAsync() { private async _refetchEthTokenStateAsync(): Promise<void> {
const etherToken = this._getEthToken(); const etherToken = this._getEthToken();
const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress; const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress;
const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync( const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(

View File

@@ -82,19 +82,19 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
tokensToTrack: [], tokensToTrack: [],
}; };
} }
public componentWillMount() { public componentWillMount(): void {
if (!_.isEmpty(this.state.orderJSON)) { if (!_.isEmpty(this.state.orderJSON)) {
// tslint:disable-next-line:no-floating-promises // tslint:disable-next-line:no-floating-promises
this._validateFillOrderFireAndForgetAsync(this.state.orderJSON); this._validateFillOrderFireAndForgetAsync(this.state.orderJSON);
} }
} }
public componentDidMount() { public componentDidMount(): void {
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
public componentWillUnmount() { public componentWillUnmount(): void {
this._isUnmounted = true; this._isUnmounted = true;
} }
public render() { public render(): React.ReactNode {
return ( return (
<div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}> <div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}>
<h3>Fill an order</h3> <h3>Fill an order</h3>
@@ -159,7 +159,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
</div> </div>
); );
} }
private _renderOrderJsonNotices() { private _renderOrderJsonNotices(): React.ReactNode {
return ( return (
<div> <div>
{!_.isUndefined(this.props.initialOrder) && {!_.isUndefined(this.props.initialOrder) &&
@@ -177,7 +177,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
</div> </div>
); );
} }
private _renderVisualOrder() { private _renderVisualOrder(): React.ReactNode {
const takerTokenAddress = this.state.parsedOrder.signedOrder.takerTokenAddress; const takerTokenAddress = this.state.parsedOrder.signedOrder.takerTokenAddress;
const takerToken = this.props.tokenByAddress[takerTokenAddress]; const takerToken = this.props.tokenByAddress[takerTokenAddress];
const orderTakerAmount = new BigNumber(this.state.parsedOrder.signedOrder.takerTokenAmount); const orderTakerAmount = new BigNumber(this.state.parsedOrder.signedOrder.takerTokenAmount);
@@ -306,7 +306,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
</div> </div>
); );
} }
private _renderFillSuccessMsg() { private _renderFillSuccessMsg(): React.ReactNode {
return ( return (
<div> <div>
Order successfully filled. See the trade details in your{' '} Order successfully filled. See the trade details in your{' '}
@@ -316,10 +316,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
</div> </div>
); );
} }
private _renderCancelSuccessMsg() { private _renderCancelSuccessMsg(): React.ReactNode {
return <div>Order successfully cancelled.</div>; return <div>Order successfully cancelled.</div>;
} }
private _onFillOrderClick() { private _onFillOrderClick(): void {
if (!this.state.isMakerTokenAddressInRegistry || !this.state.isTakerTokenAddressInRegistry) { if (!this.state.isMakerTokenAddressInRegistry || !this.state.isTakerTokenAddressInRegistry) {
this.setState({ this.setState({
isFillWarningDialogOpen: true, isFillWarningDialogOpen: true,
@@ -329,7 +329,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
this._onFillOrderClickFireAndForgetAsync(); this._onFillOrderClickFireAndForgetAsync();
} }
} }
private _onFillWarningClosed(didUserCancel: boolean) { private _onFillWarningClosed(didUserCancel: boolean): void {
this.setState({ this.setState({
isFillWarningDialogOpen: false, isFillWarningDialogOpen: false,
}); });
@@ -338,10 +338,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
this._onFillOrderClickFireAndForgetAsync(); this._onFillOrderClickFireAndForgetAsync();
} }
} }
private _onFillAmountChange(isValid: boolean, amount?: BigNumber) { private _onFillAmountChange(isValid: boolean, amount?: BigNumber): void {
this.props.dispatcher.updateOrderFillAmount(amount); this.props.dispatcher.updateOrderFillAmount(amount);
} }
private _onFillOrderJSONChanged(event: any) { private _onFillOrderJSONChanged(event: any): void {
const orderJSON = event.target.value; const orderJSON = event.target.value;
this.setState({ this.setState({
didOrderValidationRun: _.isEmpty(orderJSON) && _.isEmpty(this.state.orderJSONErrMsg), didOrderValidationRun: _.isEmpty(orderJSON) && _.isEmpty(this.state.orderJSONErrMsg),
@@ -350,7 +350,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
// tslint:disable-next-line:no-floating-promises // tslint:disable-next-line:no-floating-promises
this._validateFillOrderFireAndForgetAsync(orderJSON); this._validateFillOrderFireAndForgetAsync(orderJSON);
} }
private async _checkForUntrackedTokensAndAskToAdd() { private async _checkForUntrackedTokensAndAskToAddAsync(): Promise<void> {
if (!_.isEmpty(this.state.orderJSONErrMsg)) { if (!_.isEmpty(this.state.orderJSONErrMsg)) {
return; return;
} }
@@ -396,7 +396,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
}); });
} }
} }
private async _validateFillOrderFireAndForgetAsync(orderJSON: string) { private async _validateFillOrderFireAndForgetAsync(orderJSON: string): Promise<void> {
let orderJSONErrMsg = ''; let orderJSONErrMsg = '';
let parsedOrder: Order; let parsedOrder: Order;
let orderHash: string; let orderHash: string;
@@ -491,7 +491,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
unavailableTakerAmount, unavailableTakerAmount,
}); });
await this._checkForUntrackedTokensAndAskToAdd(); await this._checkForUntrackedTokensAndAskToAddAsync();
} }
private async _onFillOrderClickFireAndForgetAsync(): Promise<void> { private async _onFillOrderClickFireAndForgetAsync(): Promise<void> {
if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) { if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
@@ -650,7 +650,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
const roundedUnitAmount = Math.round(unitAmount.toNumber() * 100000) / 100000; const roundedUnitAmount = Math.round(unitAmount.toNumber() * 100000) / 100000;
return roundedUnitAmount; return roundedUnitAmount;
} }
private _onToggleTrackConfirmDialog(didConfirmTokenTracking: boolean) { private _onToggleTrackConfirmDialog(didConfirmTokenTracking: boolean): void {
if (!didConfirmTokenTracking) { if (!didConfirmTokenTracking) {
this.setState({ this.setState({
orderJSON: '', orderJSON: '',

View File

@@ -19,7 +19,7 @@ interface FillOrderJSONProps {
interface FillOrderJSONState {} interface FillOrderJSONState {}
export class FillOrderJSON extends React.Component<FillOrderJSONProps, FillOrderJSONState> { export class FillOrderJSON extends React.Component<FillOrderJSONProps, FillOrderJSONState> {
public render() { public render(): React.ReactNode {
const tokenAddresses = _.keys(this.props.tokenByAddress); const tokenAddresses = _.keys(this.props.tokenByAddress);
const exchangeContract = this.props.blockchain.getExchangeContractAddressIfExists(); const exchangeContract = this.props.blockchain.getExchangeContractAddressIfExists();
const hintSideToAssetToken = { const hintSideToAssetToken = {

View File

@@ -8,7 +8,7 @@ interface FillWarningDialogProps {
onToggleDialog: (didUserCancel: boolean) => void; onToggleDialog: (didUserCancel: boolean) => void;
} }
export function FillWarningDialog(props: FillWarningDialogProps) { export const FillWarningDialog = (props: FillWarningDialogProps) => {
const didCancel = true; const didCancel = true;
return ( return (
<Dialog <Dialog
@@ -42,4 +42,4 @@ export function FillWarningDialog(props: FillWarningDialogProps) {
</div> </div>
</Dialog> </Dialog>
); );
} };

View File

@@ -16,7 +16,7 @@ interface TokenSendCompletedProps {
interface TokenSendCompletedState {} interface TokenSendCompletedState {}
export class TokenSendCompleted extends React.Component<TokenSendCompletedProps, TokenSendCompletedState> { export class TokenSendCompleted extends React.Component<TokenSendCompletedProps, TokenSendCompletedState> {
public render() { public render(): React.ReactNode {
const etherScanLink = !_.isUndefined(this.props.etherScanLinkIfExists) && ( const etherScanLink = !_.isUndefined(this.props.etherScanLinkIfExists) && (
<a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank"> <a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank">
Verify on Etherscan Verify on Etherscan

View File

@@ -9,7 +9,7 @@ interface TransactionSubmittedProps {
interface TransactionSubmittedState {} interface TransactionSubmittedState {}
export class TransactionSubmitted extends React.Component<TransactionSubmittedProps, TransactionSubmittedState> { export class TransactionSubmitted extends React.Component<TransactionSubmittedProps, TransactionSubmittedState> {
public render() { public render(): React.ReactNode {
if (_.isUndefined(this.props.etherScanLinkIfExists)) { if (_.isUndefined(this.props.etherScanLinkIfExists)) {
return <div>Transaction submitted to the network</div>; return <div>Transaction submitted to the network</div>;
} else { } else {

View File

@@ -50,7 +50,7 @@ export class Footer extends React.Component<FooterProps, FooterState> {
selectedLanguage: props.translate.getLanguage(), selectedLanguage: props.translate.getLanguage(),
}; };
} }
public render() { public render(): React.ReactNode {
const menuItemsBySection: MenuItemsBySection = { const menuItemsBySection: MenuItemsBySection = {
[Key.Documentation]: [ [Key.Documentation]: [
{ {
@@ -180,14 +180,14 @@ export class Footer extends React.Component<FooterProps, FooterState> {
</div> </div>
); );
} }
private _renderIcon(fileName: string) { private _renderIcon(fileName: string): React.ReactNode {
return ( return (
<div style={{ height: ICON_DIMENSION, width: ICON_DIMENSION }}> <div style={{ height: ICON_DIMENSION, width: ICON_DIMENSION }}>
<img src={`/images/social/${fileName}`} style={{ width: ICON_DIMENSION }} /> <img src={`/images/social/${fileName}`} style={{ width: ICON_DIMENSION }} />
</div> </div>
); );
} }
private _renderMenuItem(item: FooterMenuItem) { private _renderMenuItem(item: FooterMenuItem): React.ReactNode {
const titleToIcon: { [title: string]: string } = { const titleToIcon: { [title: string]: string } = {
[this.props.translate.get(Key.RocketChat, Deco.Cap)]: 'rocketchat.png', [this.props.translate.get(Key.RocketChat, Deco.Cap)]: 'rocketchat.png',
[this.props.translate.get(Key.Blog, Deco.Cap)]: 'medium.png', [this.props.translate.get(Key.Blog, Deco.Cap)]: 'medium.png',
@@ -222,7 +222,7 @@ export class Footer extends React.Component<FooterProps, FooterState> {
</div> </div>
); );
} }
private _renderHeader(key: Key) { private _renderHeader(key: Key): React.ReactNode {
const headerStyle = { const headerStyle = {
color: colors.grey400, color: colors.grey400,
letterSpacing: 2, letterSpacing: 2,
@@ -235,7 +235,7 @@ export class Footer extends React.Component<FooterProps, FooterState> {
</div> </div>
); );
} }
private _updateLanguage(e: any, index: number, value: Language) { private _updateLanguage(e: any, index: number, value: Language): void {
this.setState({ this.setState({
selectedLanguage: value, selectedLanguage: value,
}); });

View File

@@ -79,7 +79,7 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
}, },
}; };
} }
public render() { public render(): React.ReactNode {
const dialogConfigs: DialogConfigs = this._dialogConfigsByAssetView[this.state.assetView]; const dialogConfigs: DialogConfigs = this._dialogConfigsByAssetView[this.state.assetView];
return ( return (
<Dialog <Dialog
@@ -102,7 +102,7 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
</Dialog> </Dialog>
); );
} }
private _renderConfirmTrackToken() { private _renderConfirmTrackToken(): React.ReactNode {
const token = this.props.tokenByAddress[this.state.chosenTrackTokenAddress]; const token = this.props.tokenByAddress[this.state.chosenTrackTokenAddress];
return ( return (
<TrackTokenConfirmation <TrackTokenConfirmation
@@ -113,7 +113,7 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
/> />
); );
} }
private _renderAssetPicker() { private _renderAssetPicker(): React.ReactNode {
return ( return (
<div <div
className="clearfix flex flex-wrap" className="clearfix flex flex-wrap"
@@ -128,7 +128,7 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
</div> </div>
); );
} }
private _renderGridTiles() { private _renderGridTiles(): React.ReactNode {
let isHovered; let isHovered;
let tileStyles; let tileStyles;
const gridTiles = _.map(this.props.tokenByAddress, (token: Token, address: string) => { const gridTiles = _.map(this.props.tokenByAddress, (token: Token, address: string) => {
@@ -195,19 +195,19 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
} }
return gridTiles; return gridTiles;
} }
private _onToggleHover(address: string, isHovered: boolean) { private _onToggleHover(address: string, isHovered: boolean): void {
const hoveredAddress = isHovered ? address : undefined; const hoveredAddress = isHovered ? address : undefined;
this.setState({ this.setState({
hoveredAddress, hoveredAddress,
}); });
} }
private _onCloseDialog() { private _onCloseDialog(): void {
this.setState({ this.setState({
assetView: AssetViews.ASSET_PICKER, assetView: AssetViews.ASSET_PICKER,
}); });
this.props.onTokenChosen(this.props.currentTokenAddress); this.props.onTokenChosen(this.props.currentTokenAddress);
} }
private _onChooseToken(tokenAddress: string) { private _onChooseToken(tokenAddress: string): void {
const token = this.props.tokenByAddress[tokenAddress]; const token = this.props.tokenByAddress[tokenAddress];
if (token.isTracked) { if (token.isTracked) {
this.props.onTokenChosen(tokenAddress); this.props.onTokenChosen(tokenAddress);
@@ -218,12 +218,12 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
}); });
} }
} }
private _onCustomAssetChosen() { private _onCustomAssetChosen(): void {
this.setState({ this.setState({
assetView: AssetViews.NEW_TOKEN_FORM, assetView: AssetViews.NEW_TOKEN_FORM,
}); });
} }
private _onNewTokenSubmitted(newToken: Token) { private _onNewTokenSubmitted(newToken: Token): void {
trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newToken); trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newToken);
this.props.dispatcher.addTokenToTokenByAddress(newToken); this.props.dispatcher.addTokenToTokenByAddress(newToken);
this.setState({ this.setState({
@@ -231,7 +231,7 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
}); });
this.props.onTokenChosen(newToken.address); this.props.onTokenChosen(newToken.address);
} }
private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) { private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean): Promise<void> {
if (!didUserAcceptTracking) { if (!didUserAcceptTracking) {
this.setState({ this.setState({
isAddingTokenToTracked: false, isAddingTokenToTracked: false,

View File

@@ -63,10 +63,10 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
signingState: SigningState.UNSIGNED, signingState: SigningState.UNSIGNED,
}; };
} }
public componentDidMount() { public componentDidMount(): void {
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
public render() { public render(): React.ReactNode {
const dispatcher = this.props.dispatcher; const dispatcher = this.props.dispatcher;
const depositTokenAddress = this.props.sideToAssetToken[Side.Deposit].address; const depositTokenAddress = this.props.sideToAssetToken[Side.Deposit].address;
const depositToken = this.props.tokenByAddress[depositTokenAddress]; const depositToken = this.props.tokenByAddress[depositTokenAddress];
@@ -214,13 +214,13 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
</div> </div>
); );
} }
private _onTokenAmountChange(token: Token, side: Side, isValid: boolean, amount?: BigNumber) { private _onTokenAmountChange(token: Token, side: Side, isValid: boolean, amount?: BigNumber): void {
this.props.dispatcher.updateChosenAssetToken(side, { this.props.dispatcher.updateChosenAssetToken(side, {
address: token.address, address: token.address,
amount, amount,
}); });
} }
private _onCloseOrderJSONDialog() { private _onCloseOrderJSONDialog(): void {
// Upon closing the order JSON dialog, we update the orderSalt stored in the Redux store // Upon closing the order JSON dialog, we update the orderSalt stored in the Redux store
// with a new value so that if a user signs the identical order again, the newly signed // with a new value so that if a user signs the identical order again, the newly signed
// orderHash will not collide with the previously generated orderHash. // orderHash will not collide with the previously generated orderHash.

View File

@@ -42,7 +42,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
decimalsErrText: '', decimalsErrText: '',
}; };
} }
public render() { public render(): React.ReactNode {
return ( return (
<div className="mx-auto pb2" style={{ width: 256 }}> <div className="mx-auto pb2" style={{ width: 256 }}>
<div> <div>
@@ -96,7 +96,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
</div> </div>
); );
} }
private async _onAddNewTokenClickAsync() { private async _onAddNewTokenClickAsync(): Promise<void> {
// Trigger validation of name and symbol // Trigger validation of name and symbol
this._onTokenNameChanged(undefined, this.state.name); this._onTokenNameChanged(undefined, this.state.name);
this._onTokenSymbolChanged(undefined, this.state.symbol); this._onTokenSymbolChanged(undefined, this.state.symbol);
@@ -152,7 +152,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
}; };
this.props.onNewTokenSubmitted(newToken); this.props.onNewTokenSubmitted(newToken);
} }
private _onTokenNameChanged(e: any, name: string) { private _onTokenNameChanged(e: any, name: string): void {
let nameErrText = ''; let nameErrText = '';
const maxLength = 30; const maxLength = 30;
const tokens = _.values(this.props.tokenByAddress); const tokens = _.values(this.props.tokenByAddress);
@@ -173,7 +173,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
nameErrText, nameErrText,
}); });
} }
private _onTokenSymbolChanged(e: any, symbol: string) { private _onTokenSymbolChanged(e: any, symbol: string): void {
let symbolErrText = ''; let symbolErrText = '';
const maxLength = 5; const maxLength = 5;
const tokens = _.values(this.props.tokenByAddress); const tokens = _.values(this.props.tokenByAddress);
@@ -193,7 +193,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
symbolErrText, symbolErrText,
}); });
} }
private _onTokenDecimalsChanged(e: any, decimals: string) { private _onTokenDecimalsChanged(e: any, decimals: string): void {
let decimalsErrText = ''; let decimalsErrText = '';
const maxLength = 2; const maxLength = 2;
if (decimals === '') { if (decimals === '') {
@@ -209,20 +209,20 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
decimalsErrText, decimalsErrText,
}); });
} }
private _onTokenAddressChanged(address?: string) { private _onTokenAddressChanged(address?: string): void {
if (!_.isUndefined(address)) { if (!_.isUndefined(address)) {
this.setState({ this.setState({
address, address,
}); });
} }
} }
private _isValidName(input: string) { private _isValidName(input: string): boolean {
return /^[a-z0-9 ]+$/i.test(input); return /^[a-z0-9 ]+$/i.test(input);
} }
private _isInteger(input: string) { private _isInteger(input: string): boolean {
return /^[0-9]+$/i.test(input); return /^[0-9]+$/i.test(input);
} }
private _isAlphanumeric(input: string) { private _isAlphanumeric(input: string): boolean {
return /^[a-zA-Z0-9]+$/i.test(input); return /^[a-zA-Z0-9]+$/i.test(input);
} }
} }

View File

@@ -29,14 +29,14 @@ export class AddressInput extends React.Component<AddressInputProps, AddressInpu
errMsg: '', errMsg: '',
}; };
} }
public componentWillReceiveProps(nextProps: AddressInputProps) { public componentWillReceiveProps(nextProps: AddressInputProps): void {
if (nextProps.shouldShowIncompleteErrs && this.props.isRequired && this.state.address === '') { if (nextProps.shouldShowIncompleteErrs && this.props.isRequired && this.state.address === '') {
this.setState({ this.setState({
errMsg: 'Address is required', errMsg: 'Address is required',
}); });
} }
} }
public render() { public render(): React.ReactNode {
const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label; const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
const labelDisplay = this.props.shouldHideLabel ? 'hidden' : 'block'; const labelDisplay = this.props.shouldHideLabel ? 'hidden' : 'block';
const hintText = this.props.hintText ? this.props.hintText : ''; const hintText = this.props.hintText ? this.props.hintText : '';
@@ -57,7 +57,7 @@ export class AddressInput extends React.Component<AddressInputProps, AddressInpu
</div> </div>
); );
} }
private _onOrderTakerAddressUpdated(e: any) { private _onOrderTakerAddressUpdated(e: any): void {
const address = e.target.value.toLowerCase(); const address = e.target.value.toLowerCase();
const isValidAddress = addressUtils.isAddress(address) || address === ''; const isValidAddress = addressUtils.isAddress(address) || address === '';
const errMsg = isValidAddress ? '' : 'Invalid ethereum address'; const errMsg = isValidAddress ? '' : 'Invalid ethereum address';

View File

@@ -63,7 +63,7 @@ export class AllowanceToggle extends React.Component<AllowanceToggleProps, Allow
prevAllowance: props.tokenState.allowance, prevAllowance: props.tokenState.allowance,
}; };
} }
public componentWillReceiveProps(nextProps: AllowanceToggleProps) { public componentWillReceiveProps(nextProps: AllowanceToggleProps): void {
if (!nextProps.tokenState.allowance.eq(this.state.prevAllowance)) { if (!nextProps.tokenState.allowance.eq(this.state.prevAllowance)) {
this.setState({ this.setState({
isSpinnerVisible: false, isSpinnerVisible: false,
@@ -71,7 +71,7 @@ export class AllowanceToggle extends React.Component<AllowanceToggleProps, Allow
}); });
} }
} }
public render() { public render(): React.ReactNode {
return ( return (
<div className="flex"> <div className="flex">
<div> <div>
@@ -128,7 +128,7 @@ export class AllowanceToggle extends React.Component<AllowanceToggleProps, Allow
await errorReporter.reportAsync(err); await errorReporter.reportAsync(err);
} }
} }
private _isAllowanceSet() { private _isAllowanceSet(): boolean {
return !this.props.tokenState.allowance.eq(0); return !this.props.tokenState.allowance.eq(0);
} }
} }

View File

@@ -46,7 +46,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
amountString, amountString,
}; };
} }
public componentWillReceiveProps(nextProps: BalanceBoundedInputProps) { public componentWillReceiveProps(nextProps: BalanceBoundedInputProps): void {
if (nextProps === this.props) { if (nextProps === this.props) {
return; return;
} }
@@ -76,7 +76,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
}); });
} }
} }
public render() { public render(): React.ReactNode {
let errorText; let errorText;
if (this.props.shouldShowErrs) { if (this.props.shouldShowErrs) {
errorText = errorText =
@@ -104,7 +104,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
/> />
); );
} }
private _onValueChange(e: any, amountString: string) { private _onValueChange(e: any, amountString: string): void {
const errMsg = this._validate(amountString, this.props.balance); const errMsg = this._validate(amountString, this.props.balance);
this.setState( this.setState(
{ {
@@ -135,7 +135,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
const errMsg = _.isUndefined(this.props.validate) ? undefined : this.props.validate(amount); const errMsg = _.isUndefined(this.props.validate) ? undefined : this.props.validate(amount);
return errMsg; return errMsg;
} }
private _renderIncreaseBalanceLink() { private _renderIncreaseBalanceLink(): React.ReactNode {
if (this.props.shouldHideVisitBalancesLink) { if (this.props.shouldHideVisitBalancesLink) {
return null; return null;
} }

View File

@@ -29,7 +29,7 @@ export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmou
shouldShowUnderline: true, shouldShowUnderline: true,
style: { height: 63 }, style: { height: 63 },
}; };
public render() { public render(): React.ReactNode {
const amount = this.props.amount const amount = this.props.amount
? ZeroEx.toUnitAmount(this.props.amount, constants.DECIMAL_PLACES_ETH) ? ZeroEx.toUnitAmount(this.props.amount, constants.DECIMAL_PLACES_ETH)
: undefined; : undefined;
@@ -52,7 +52,7 @@ export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmou
</div> </div>
); );
} }
private _onChange(isValid: boolean, amount?: BigNumber) { private _onChange(isValid: boolean, amount?: BigNumber): void {
const baseUnitAmountIfExists = _.isUndefined(amount) const baseUnitAmountIfExists = _.isUndefined(amount)
? undefined ? undefined
: ZeroEx.toBaseUnitAmount(amount, constants.DECIMAL_PLACES_ETH); : ZeroEx.toBaseUnitAmount(amount, constants.DECIMAL_PLACES_ETH);

View File

@@ -30,7 +30,7 @@ export class ExpirationInput extends React.Component<ExpirationInputProps, Expir
timeMoment: didUserSetExpiry ? expirationMoment : undefined, timeMoment: didUserSetExpiry ? expirationMoment : undefined,
}; };
} }
public render() { public render(): React.ReactNode {
const date = this.state.dateMoment ? this.state.dateMoment.toDate() : undefined; const date = this.state.dateMoment ? this.state.dateMoment.toDate() : undefined;
const time = this.state.timeMoment ? this.state.timeMoment.toDate() : undefined; const time = this.state.timeMoment ? this.state.timeMoment.toDate() : undefined;
return ( return (
@@ -72,7 +72,7 @@ export class ExpirationInput extends React.Component<ExpirationInputProps, Expir
.startOf('day') .startOf('day')
.isBefore(this._earliestPickableMoment); .isBefore(this._earliestPickableMoment);
} }
private _clearDates() { private _clearDates(): void {
this.setState({ this.setState({
dateMoment: undefined, dateMoment: undefined,
timeMoment: undefined, timeMoment: undefined,
@@ -80,7 +80,7 @@ export class ExpirationInput extends React.Component<ExpirationInputProps, Expir
const defaultDateTime = utils.initialOrderExpiryUnixTimestampSec(); const defaultDateTime = utils.initialOrderExpiryUnixTimestampSec();
this.props.updateOrderExpiry(defaultDateTime); this.props.updateOrderExpiry(defaultDateTime);
} }
private _onDateChanged(e: any, date: Date) { private _onDateChanged(e: any, date: Date): void {
const dateMoment = moment(date); const dateMoment = moment(date);
this.setState({ this.setState({
dateMoment, dateMoment,
@@ -88,7 +88,7 @@ export class ExpirationInput extends React.Component<ExpirationInputProps, Expir
const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, this.state.timeMoment); const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, this.state.timeMoment);
this.props.updateOrderExpiry(timestamp); this.props.updateOrderExpiry(timestamp);
} }
private _onTimeChanged(e: any, time: Date) { private _onTimeChanged(e: any, time: Date): void {
const timeMoment = moment(time); const timeMoment = moment(time);
this.setState({ this.setState({
timeMoment, timeMoment,

Some files were not shown because too many files have changed in this diff Show More