From bb4c748bf1e93d1f2c98514c574ba67678b0ed59 Mon Sep 17 00:00:00 2001 From: Cavan Date: Thu, 7 Jun 2018 09:42:50 -0600 Subject: Formatting and standards updates --- packages/subproviders/src/index.ts | 1 + .../src/subproviders/eth_lightwallet.ts | 88 ++++++++++ .../test/unit/eth_lightwallet_subprovider_test.ts | 183 +++++++++++++++++++++ .../types/eth-lightwallet/index.d.ts | 48 ++++++ 4 files changed, 320 insertions(+) create mode 100644 packages/subproviders/src/subproviders/eth_lightwallet.ts create mode 100644 packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts create mode 100644 packages/typescript-typings/types/eth-lightwallet/index.d.ts (limited to 'packages') diff --git a/packages/subproviders/src/index.ts b/packages/subproviders/src/index.ts index 6cc650a4d..0e1579706 100644 --- a/packages/subproviders/src/index.ts +++ b/packages/subproviders/src/index.ts @@ -15,6 +15,7 @@ export { Subprovider } from './subproviders/subprovider'; export { NonceTrackerSubprovider } from './subproviders/nonce_tracker'; export { PrivateKeyWalletSubprovider } from './subproviders/private_key_wallet'; export { MnemonicWalletSubprovider } from './subproviders/mnemonic_wallet'; +export { EthLightwalletSubprovider } from './subproviders/eth_lightwallet'; export { Callback, ErrorCallback, diff --git a/packages/subproviders/src/subproviders/eth_lightwallet.ts b/packages/subproviders/src/subproviders/eth_lightwallet.ts new file mode 100644 index 000000000..af4ea77e9 --- /dev/null +++ b/packages/subproviders/src/subproviders/eth_lightwallet.ts @@ -0,0 +1,88 @@ +import { assert } from '@0xproject/assert'; +import { ECSignatureBuffer } from '@0xproject/types'; +import { addressUtils } from '@0xproject/utils'; +import * as lightwallet from 'eth-lightwallet'; +import EthereumTx = require('ethereumjs-tx'); +import * as _ from 'lodash'; + +import { PartialTxParams, WalletSubproviderErrors } from '../types'; + +import { BaseWalletSubprovider } from './base_wallet_subprovider'; + +/* + * This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) subprovider interface. + * This subprovider intercepts all account related RPC requests (e.g message/transaction signing, etc...) and + * re-routes them to [eth-lightwallet](https://github.com/ConsenSys/eth-lightwallet). + */ +export class EthLightwalletSubprovider extends BaseWalletSubprovider { + private _signing: lightwallet.signing; + private _keystore: lightwallet.keystore; + private _pwDerivedKey: Uint8Array; + /** + * Instantiates a EthLightwalletSubprovider + * @param signing The lightwallet module containing signing functions + * @param keystore An instance of the lightwallet keystore + * @param pwDerivedKey The users password derived key + */ + constructor(signing: lightwallet.signing, keystore: lightwallet.keystore, pwDerivedKey: Uint8Array) { + super(); + + this._signing = signing; + this._keystore = keystore; + this._pwDerivedKey = pwDerivedKey; + } + /** + * Retrieve the accounts associated with the eth-lightwallet instance. + * This method is implicitly called when issuing a `eth_accounts` JSON RPC request + * via your providerEngine instance. + * + * @return An array of accounts + */ + public async getAccountsAsync(): Promise { + const accounts = this._keystore.getAddresses(); + return accounts; + } + /** + * Signs a transaction with the account specificed by the `from` field in txParams. + * If you've added this Subprovider to your app's provider, you can simply send + * an `eth_sendTransaction` JSON RPC request, and this method will be called auto-magically. + * If you are not using this via a ProviderEngine instance, you can call it directly. + * @param txParams Parameters of the transaction to sign + * @return Signed transaction hex string + */ + public async signTransactionAsync(txParams: PartialTxParams): Promise { + if (_.isUndefined(txParams.from) || !addressUtils.isAddress(txParams.from)) { + throw new Error(WalletSubproviderErrors.FromAddressMissingOrInvalid); + } + + const tx = new EthereumTx(txParams); + const txHex = tx.serialize().toString('hex'); + let signedTxHex: string = this._signing.signTx(this._keystore, this._pwDerivedKey, txHex, txParams.from); + + signedTxHex = `0x${signedTxHex}`; + + return signedTxHex; + } + /** + * Sign a personal Ethereum signed message. The signing account will be the account + * associated with the provided address. + * If you've added the EthLightwalletSubprovider to your app's provider, you can simply send an `eth_sign` + * or `personal_sign` JSON RPC request, and this method will be called auto-magically. + * If you are not using this via a ProviderEngine instance, you can call it directly. + * @param data Hex string message to sign + * @param address Address of the account to sign with + * @return Signature hex string (order: rsv) + */ + public async signPersonalMessageAsync(data: string, address: string): Promise { + if (_.isUndefined(data)) { + throw new Error(WalletSubproviderErrors.DataMissingForSignPersonalMessage); + } + assert.isHexString('data', data); + assert.isETHAddressHex('address', address); + const result: ECSignatureBuffer = this._signing.signMsgHash(this._keystore, this._pwDerivedKey, data, address); + + const signature = this._signing.concatSig(result); + + return signature; + } +} diff --git a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts new file mode 100644 index 000000000..762163338 --- /dev/null +++ b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts @@ -0,0 +1,183 @@ +import { JSONRPCResponsePayload } from '@0xproject/types'; +import * as chai from 'chai'; +import * as lightwallet from 'eth-lightwallet'; +import Web3ProviderEngine = require('web3-provider-engine'); +import RpcSubprovider = require('web3-provider-engine/subproviders/rpc'); + +import { EthLightwalletSubprovider } from '../../src'; +import { DoneCallback } from '../../src/types'; +import { chaiSetup } from '../chai_setup'; +import { ganacheSubprovider } from '../utils/ganache_subprovider'; +import { reportCallbackErrors } from '../utils/report_callback_errors'; + +chaiSetup.configure(); +const expect = chai.expect; +const FAKE_ADDRESS = '0x44be42fd88e22387c43ba9b75941aa3e680dae25'; +const NUM_GENERATED_ADDRESSES = 10; +const PASSWORD = 'supersecretpassword99'; +const SEED_PHRASE = 'dilemma hollow outer pony cube season start stereo surprise when edit blast'; +const SALT = 'kvODghzs7Ff1uqHyI0P3wI4Hso4w4iWT2e9qmrWz0y4'; +const HD_PATH_STRING = `m/44'/60'/0'`; + +describe('EthLightwalletSubprovider', () => { + let ethLightwalletSubprovider: EthLightwalletSubprovider; + before(async () => { + const options = { + password: PASSWORD, + seedPhrase: SEED_PHRASE, + salt: SALT, + hdPathString: HD_PATH_STRING, + }; + + const createVaultAsync = async (vaultOptions: lightwallet.VaultOptions) => { + return new Promise(resolve => { + // Create Vault + lightwallet.keystore.createVault(vaultOptions, (err: Error, vaultKeystore) => { + resolve(vaultKeystore); + }); + }); + }; + + const deriveKeyFromPasswordAsync = async (vaultKeystore: lightwallet.keystore) => { + return new Promise(resolve => { + vaultKeystore.keyFromPassword(PASSWORD, (err: Error, passwordDerivedKey: Uint8Array) => { + resolve(passwordDerivedKey); + }); + }); + }; + + const keystore: lightwallet.keystore = await createVaultAsync(options); + const pwDerivedKey: Uint8Array = await deriveKeyFromPasswordAsync(keystore); + + // Generate 10 addresses + keystore.generateNewAddress(pwDerivedKey, NUM_GENERATED_ADDRESSES); + + // Initialize Subprovider + ethLightwalletSubprovider = new EthLightwalletSubprovider(lightwallet.signing, keystore, pwDerivedKey); + }); + describe('direct method calls', () => { + describe('success cases', () => { + it('returns a list of accounts', async () => { + const accounts = await ethLightwalletSubprovider.getAccountsAsync(); + expect(accounts[0]).to.be.equal(FAKE_ADDRESS); + expect(accounts.length).to.be.equal(NUM_GENERATED_ADDRESSES); + }); + it('signs a personal message hash', async () => { + const signingAccount = (await ethLightwalletSubprovider.getAccountsAsync())[0]; + + // Keccak-256 hash of 'hello world' + const messageHash = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'; + const ecSignatureHex = await ethLightwalletSubprovider.signPersonalMessageAsync( + messageHash, + signingAccount, + ); + expect(ecSignatureHex).to.be.equal( + // tslint:disable-next-line:max-line-length + '0xa46b696c1aa8f91dbb33d1a66f6440bf3cf334c9dc45dc389668c1e60e2db31e259400b41f31632fa994837054c5345c88dc455c13931332489029adee6fd24d1b', + ); + }); + }); + }); + describe('calls through a provider', () => { + let provider: Web3ProviderEngine; + before(() => { + provider = new Web3ProviderEngine(); + provider.addProvider(ethLightwalletSubprovider); + provider.addProvider(ganacheSubprovider); + provider.start(); + }); + describe('success cases', () => { + it('returns a list of accounts', (done: DoneCallback) => { + const payload = { + jsonrpc: '2.0', + method: 'eth_accounts', + params: [], + id: 1, + }; + const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { + expect(err).to.be.a('null'); + expect(response.result.length).to.be.equal(NUM_GENERATED_ADDRESSES); + expect(response.result[0]).to.be.equal(FAKE_ADDRESS); + done(); + }); + provider.sendAsync(payload, callback); + }); + it('signs a personal message hash with eth_sign', (done: DoneCallback) => { + // Keccak-256 hash of 'hello world' + const messageHash = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'; + const payload = { + jsonrpc: '2.0', + method: 'eth_sign', + params: ['0x44be42fd88e22387c43ba9b75941aa3e680dae25', messageHash], + id: 1, + }; + const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { + expect(err).to.be.a('null'); + expect(response.result).to.be.equal( + // tslint:disable-next-line:max-line-length + '0xa46b696c1aa8f91dbb33d1a66f6440bf3cf334c9dc45dc389668c1e60e2db31e259400b41f31632fa994837054c5345c88dc455c13931332489029adee6fd24d1b', + ); + done(); + }); + provider.sendAsync(payload, callback); + }); + it('signs a transaction', (done: DoneCallback) => { + const tx = { + to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66', + value: '0x00', + gasPrice: '0x00', + nonce: '0x00', + gas: '0x00', + from: '0x44be42fd88e22387c43ba9b75941aa3e680dae25', + }; + const payload = { + jsonrpc: '2.0', + method: 'eth_signTransaction', + params: [tx], + id: 1, + }; + const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { + const expectedResponseLength = 192; + + expect(err).to.be.a('null'); + expect(response.result.raw.length).to.be.equal(expectedResponseLength); + expect(response.result.raw.substr(0, 2)).to.be.equal('0x'); + done(); + }); + provider.sendAsync(payload, callback); + }); + }); + describe('failure cases', () => { + it('should throw if `data` param not hex when calling eth_sign', (done: DoneCallback) => { + const nonHexMessage = 'hello world'; + const payload = { + jsonrpc: '2.0', + method: 'eth_sign', + params: ['0x0000000000000000000000000000000000000000', nonHexMessage], + id: 1, + }; + const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { + expect(err).to.not.be.a('null'); + expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world'); + done(); + }); + provider.sendAsync(payload, callback); + }); + it('should throw if `data` param not hex when calling personal_sign', (done: DoneCallback) => { + const nonHexMessage = 'hello world'; + const payload = { + jsonrpc: '2.0', + method: 'personal_sign', + params: [nonHexMessage, '0x0000000000000000000000000000000000000000'], + id: 1, + }; + const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { + expect(err).to.not.be.a('null'); + expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world'); + done(); + }); + provider.sendAsync(payload, callback); + }); + }); + }); +}); diff --git a/packages/typescript-typings/types/eth-lightwallet/index.d.ts b/packages/typescript-typings/types/eth-lightwallet/index.d.ts new file mode 100644 index 000000000..d31e67fc4 --- /dev/null +++ b/packages/typescript-typings/types/eth-lightwallet/index.d.ts @@ -0,0 +1,48 @@ +// eth-lightwallet declarations +declare module 'eth-lightwallet' { + import { ECSignatureBuffer } from '@0xproject/types'; + + interface signing { + signTx(keystore: keystore, pwDerivedKey: Uint8Array, rawTx: string, signingAddress: string): string; + signMsg( + keystore: keystore, + pwDerivedKey: Uint8Array, + rawMsg: string, + signingAddress: string, + ): ECSignatureBuffer; + signMsgHash( + keystore: keystore, + pwDerivedKey: Uint8Array, + msgHash: string, + signingAddress: string, + ): ECSignatureBuffer; + concatSig(signature: any): string; + } + export const signing: signing; + + interface VaultOptions { + password: string; + seedPhrase: string; + salt?: string; + hdPathString: string; + } + export class keystore { + public static createVault( + options: VaultOptions, + callback?: (error: Error, keystore: keystore) => void, + ): keystore; + public static generateRandomSeed(): string; + public static isSeedValid(seed: string): boolean; + public static deserialize(keystore: string): keystore; + public serialize(): string; + public keyFromPassword( + password: string, + callback?: (error: Error, pwDerivedKey: Uint8Array) => void, + ): Uint8Array; + public isDerivedKeyCorrect(pwDerivedKey: Uint8Array): boolean; + public generateNewAddress(pwDerivedKey: Uint8Array, numberOfAddresses: number): void; + public getSeed(pwDerivedKey: Uint8Array): string; + public exportPrivateKey(address: string, pwDerivedKey: Uint8Array): string; + public getAddresses(): string[]; + } +} -- cgit v1.2.3 From 76f4d67f33af208e83eea5bcfa8802ce0e482901 Mon Sep 17 00:00:00 2001 From: Cavan Date: Wed, 6 Jun 2018 00:01:19 -0600 Subject: Remove timestamps and fix typings --- packages/subproviders/CHANGELOG.json | 8 ++++++++ packages/subproviders/src/subproviders/eth_lightwallet.ts | 14 ++++++++++++-- .../typescript-typings/types/eth-lightwallet/index.d.ts | 8 +++++++- 3 files changed, 27 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/subproviders/CHANGELOG.json b/packages/subproviders/CHANGELOG.json index 65a74f7a8..c4dca2864 100644 --- a/packages/subproviders/CHANGELOG.json +++ b/packages/subproviders/CHANGELOG.json @@ -1,4 +1,12 @@ [ + { + "version": "0.11.0", + "changes": [ + { + "note": "Add `EthLightwalletSubprovider`" + } + ] + }, { "timestamp": 1529397769, "version": "0.10.4", diff --git a/packages/subproviders/src/subproviders/eth_lightwallet.ts b/packages/subproviders/src/subproviders/eth_lightwallet.ts index af4ea77e9..fedcc9578 100644 --- a/packages/subproviders/src/subproviders/eth_lightwallet.ts +++ b/packages/subproviders/src/subproviders/eth_lightwallet.ts @@ -57,7 +57,12 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { const tx = new EthereumTx(txParams); const txHex = tx.serialize().toString('hex'); - let signedTxHex: string = this._signing.signTx(this._keystore, this._pwDerivedKey, txHex, txParams.from); + let signedTxHex: string = this._signing.signTx( + this._keystore, + this._pwDerivedKey, + txHex, + txParams.from, + ); signedTxHex = `0x${signedTxHex}`; @@ -79,7 +84,12 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { } assert.isHexString('data', data); assert.isETHAddressHex('address', address); - const result: ECSignatureBuffer = this._signing.signMsgHash(this._keystore, this._pwDerivedKey, data, address); + const result: ECSignatureBuffer = await this._signing.signMsgHash( + this._keystore, + this._pwDerivedKey, + data, + address, + ); const signature = this._signing.concatSig(result); diff --git a/packages/typescript-typings/types/eth-lightwallet/index.d.ts b/packages/typescript-typings/types/eth-lightwallet/index.d.ts index d31e67fc4..b871fb289 100644 --- a/packages/typescript-typings/types/eth-lightwallet/index.d.ts +++ b/packages/typescript-typings/types/eth-lightwallet/index.d.ts @@ -3,7 +3,12 @@ declare module 'eth-lightwallet' { import { ECSignatureBuffer } from '@0xproject/types'; interface signing { - signTx(keystore: keystore, pwDerivedKey: Uint8Array, rawTx: string, signingAddress: string): string; + signTx( + keystore: keystore, + pwDerivedKey: Uint8Array, + rawTx: string, + signingAddress: string, + ): string; signMsg( keystore: keystore, pwDerivedKey: Uint8Array, @@ -26,6 +31,7 @@ declare module 'eth-lightwallet' { salt?: string; hdPathString: string; } + export class keystore { public static createVault( options: VaultOptions, -- cgit v1.2.3 From db5880539b7a92a80d79692fbc70d46a326b1462 Mon Sep 17 00:00:00 2001 From: Cavan Date: Tue, 5 Jun 2018 17:31:36 -0600 Subject: Update changelogs --- packages/types/CHANGELOG.json | 8 ++++++++ packages/typescript-typings/CHANGELOG.json | 8 ++++++++ 2 files changed, 16 insertions(+) (limited to 'packages') diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index 40197ab92..5e14faeb6 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -1,4 +1,12 @@ [ + { + "version": "0.8.2", + "changes": [ + { + "note": "Add `ECSignatureBuffer`" + } + ] + }, { "timestamp": 1529397769, "version": "0.8.1", diff --git a/packages/typescript-typings/CHANGELOG.json b/packages/typescript-typings/CHANGELOG.json index 5b5d5c31d..e5b9edc70 100644 --- a/packages/typescript-typings/CHANGELOG.json +++ b/packages/typescript-typings/CHANGELOG.json @@ -1,4 +1,12 @@ [ + { + "version": "0.4.2", + "changes": [ + { + "note": "Add types for `eth-lightwallet`" + } + ] + }, { "timestamp": 1529397769, "version": "0.4.1", -- cgit v1.2.3 From 235d78565e4d809d3ec1b91174fd0a831c126202 Mon Sep 17 00:00:00 2001 From: Cavan Date: Mon, 4 Jun 2018 16:24:37 -0600 Subject: Format subprovider using prettier --- .../src/subproviders/eth_lightwallet.ts | 2 ++ .../types/eth-lightwallet/index.d.ts | 24 ++++++---------------- 2 files changed, 8 insertions(+), 18 deletions(-) (limited to 'packages') diff --git a/packages/subproviders/src/subproviders/eth_lightwallet.ts b/packages/subproviders/src/subproviders/eth_lightwallet.ts index fedcc9578..970c5d981 100644 --- a/packages/subproviders/src/subproviders/eth_lightwallet.ts +++ b/packages/subproviders/src/subproviders/eth_lightwallet.ts @@ -62,6 +62,7 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { this._pwDerivedKey, txHex, txParams.from, + this._keystore.hdPathString, ); signedTxHex = `0x${signedTxHex}`; @@ -89,6 +90,7 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { this._pwDerivedKey, data, address, + this._keystore.hdPathString, ); const signature = this._signing.concatSig(result); diff --git a/packages/typescript-typings/types/eth-lightwallet/index.d.ts b/packages/typescript-typings/types/eth-lightwallet/index.d.ts index b871fb289..a226d8049 100644 --- a/packages/typescript-typings/types/eth-lightwallet/index.d.ts +++ b/packages/typescript-typings/types/eth-lightwallet/index.d.ts @@ -2,41 +2,29 @@ declare module 'eth-lightwallet' { import { ECSignatureBuffer } from '@0xproject/types'; - interface signing { - signTx( + export class signing { + public static signTx( keystore: keystore, pwDerivedKey: Uint8Array, rawTx: string, signingAddress: string, ): string; - signMsg( + public static signMsg( keystore: keystore, pwDerivedKey: Uint8Array, rawMsg: string, signingAddress: string, ): ECSignatureBuffer; - signMsgHash( + public static signMsgHash( keystore: keystore, pwDerivedKey: Uint8Array, msgHash: string, signingAddress: string, ): ECSignatureBuffer; - concatSig(signature: any): string; + public static concatSig(signature: any): string; } - export const signing: signing; - - interface VaultOptions { - password: string; - seedPhrase: string; - salt?: string; - hdPathString: string; - } - export class keystore { - public static createVault( - options: VaultOptions, - callback?: (error: Error, keystore: keystore) => void, - ): keystore; + public static createVault(options: any, callback?: (error: Error, keystore: keystore) => void): keystore; public static generateRandomSeed(): string; public static isSeedValid(seed: string): boolean; public static deserialize(keystore: string): keystore; -- cgit v1.2.3 From 1821f60fb5ddd4a36f34cce94acabba32b4236c6 Mon Sep 17 00:00:00 2001 From: Cavan Date: Mon, 4 Jun 2018 16:04:25 -0600 Subject: Move eth-lightwallet declaration to typings --- packages/types/src/index.ts | 6 +++ .../types/eth-lightwallet/index.d.ts | 58 ++++++++-------------- 2 files changed, 26 insertions(+), 38 deletions(-) (limited to 'packages') diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index e5a0f41a9..390d2f50c 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -48,6 +48,12 @@ export interface ECSignature { s: string; } +export interface ECSignatureBuffer { + v: number; + r: Buffer; + s: Buffer; +} + /** * Validator signature components */ diff --git a/packages/typescript-typings/types/eth-lightwallet/index.d.ts b/packages/typescript-typings/types/eth-lightwallet/index.d.ts index a226d8049..76f910d9c 100644 --- a/packages/typescript-typings/types/eth-lightwallet/index.d.ts +++ b/packages/typescript-typings/types/eth-lightwallet/index.d.ts @@ -1,42 +1,24 @@ // eth-lightwallet declarations declare module 'eth-lightwallet' { - import { ECSignatureBuffer } from '@0xproject/types'; + import { ECSignatureBuffer } from "@0xproject/types"; - export class signing { - public static signTx( - keystore: keystore, - pwDerivedKey: Uint8Array, - rawTx: string, - signingAddress: string, - ): string; - public static signMsg( - keystore: keystore, - pwDerivedKey: Uint8Array, - rawMsg: string, - signingAddress: string, - ): ECSignatureBuffer; - public static signMsgHash( - keystore: keystore, - pwDerivedKey: Uint8Array, - msgHash: string, - signingAddress: string, - ): ECSignatureBuffer; - public static concatSig(signature: any): string; - } - export class keystore { - public static createVault(options: any, callback?: (error: Error, keystore: keystore) => void): keystore; - public static generateRandomSeed(): string; - public static isSeedValid(seed: string): boolean; - public static deserialize(keystore: string): keystore; - public serialize(): string; - public keyFromPassword( - password: string, - callback?: (error: Error, pwDerivedKey: Uint8Array) => void, - ): Uint8Array; - public isDerivedKeyCorrect(pwDerivedKey: Uint8Array): boolean; - public generateNewAddress(pwDerivedKey: Uint8Array, numberOfAddresses: number): void; - public getSeed(pwDerivedKey: Uint8Array): string; - public exportPrivateKey(address: string, pwDerivedKey: Uint8Array): string; - public getAddresses(): string[]; - } + export class signing { + public static signTx(keystore: keystore, pwDerivedKey: Uint8Array, rawTx: string, signingAddress: string): string; + public static signMsg(keystore: keystore, pwDerivedKey: Uint8Array, rawMsg: string, signingAddress: string): ECSignatureBuffer; + public static signMsgHash(keystore: keystore, pwDerivedKey: Uint8Array, msgHash: string, signingAddress: string): ECSignatureBuffer; + public static concatSig(signature: any): string; + } + export class keystore { + public static createVault(options: any, callback?: (error: Error, keystore: keystore) => void): keystore; + public static generateRandomSeed(): string; + public static isSeedValid(seed: string): boolean; + public static deserialize(keystore: string): keystore; + public serialize(): string; + public keyFromPassword(password: string, callback?: (error: Error, pwDerivedKey: Uint8Array) => void): Uint8Array; + public isDerivedKeyCorrect(pwDerivedKey: Uint8Array): boolean; + public generateNewAddress(pwDerivedKey: Uint8Array, numberOfAddresses: number): void; + public getSeed(pwDerivedKey: Uint8Array): string; + public exportPrivateKey(address: string, pwDerivedKey: Uint8Array): string; + public getAddresses(): string[]; + } } -- cgit v1.2.3 From 7ce1e9b18d30cb76dd61f3859164cb09d091a3dd Mon Sep 17 00:00:00 2001 From: Cavan Date: Mon, 4 Jun 2018 14:48:18 -0600 Subject: Add eth-lightwallet subprovider and tests --- packages/subproviders/package.json | 1 + packages/subproviders/src/globals.d.ts | 28 +++++++ packages/subproviders/src/index.ts | 2 +- .../subproviders/eth_lightwallet_subprovider.ts | 88 ++++++++++++++++++++++ .../test/unit/eth_lightwallet_subprovider_test.ts | 6 +- 5 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts (limited to 'packages') diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index a04546bc1..c3e588718 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -49,6 +49,7 @@ "ethereum-types": "^0.0.1", "bip39": "^2.5.0", "bn.js": "^4.11.8", + "eth-lightwallet": "^3.0.1", "ethereumjs-tx": "^1.3.3", "ethereumjs-util": "^5.1.1", "ganache-core": "0xProject/ganache-core", diff --git a/packages/subproviders/src/globals.d.ts b/packages/subproviders/src/globals.d.ts index 4b3ecdf3c..1e104053f 100644 --- a/packages/subproviders/src/globals.d.ts +++ b/packages/subproviders/src/globals.d.ts @@ -16,6 +16,11 @@ interface ECSignature { r: string; s: string; } +interface ECSignatureBuffer { + v: number; + r: Buffer; + s: Buffer; +} interface LedgerTransport { close(): Promise; @@ -57,3 +62,26 @@ declare module '*.json' { export default json; /* tslint:enable */ } + +// eth-lightwallet declarations +declare module 'eth-lightwallet' { + export class signing { + public static signTx(keystore: keystore, pwDerivedKey: Uint8Array, rawTx: string, signingAddress: string): string; + public static signMsg(keystore: keystore, pwDerivedKey: Uint8Array, rawMsg: string, signingAddress: string): ECSignatureBuffer; + public static signMsgHash(keystore: keystore, pwDerivedKey: Uint8Array, msgHash: string, signingAddress: string): ECSignatureBuffer; + public static concatSig(signature: any): string; + } + export class keystore { + public static createVault(options: any, callback?: (error: Error, keystore: keystore) => void): keystore; + public static generateRandomSeed(): string; + public static isSeedValid(seed: string): boolean; + public static deserialize(keystore: string): keystore; + public serialize(): string; + public keyFromPassword(password: string, callback?: (error: Error, pwDerivedKey: Uint8Array) => void): Uint8Array; + public isDerivedKeyCorrect(pwDerivedKey: Uint8Array): boolean; + public generateNewAddress(pwDerivedKey: Uint8Array, numberOfAddresses: number): void; + public getSeed(pwDerivedKey: Uint8Array): string; + public exportPrivateKey(address: string, pwDerivedKey: Uint8Array): string; + public getAddresses(): string[]; + } +} diff --git a/packages/subproviders/src/index.ts b/packages/subproviders/src/index.ts index 0e1579706..06d5871f9 100644 --- a/packages/subproviders/src/index.ts +++ b/packages/subproviders/src/index.ts @@ -15,7 +15,7 @@ export { Subprovider } from './subproviders/subprovider'; export { NonceTrackerSubprovider } from './subproviders/nonce_tracker'; export { PrivateKeyWalletSubprovider } from './subproviders/private_key_wallet'; export { MnemonicWalletSubprovider } from './subproviders/mnemonic_wallet'; -export { EthLightwalletSubprovider } from './subproviders/eth_lightwallet'; +export { EthLightwalletSubprovider } from './subproviders/eth_lightwallet_subprovider'; export { Callback, ErrorCallback, diff --git a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts new file mode 100644 index 000000000..7507eeb49 --- /dev/null +++ b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts @@ -0,0 +1,88 @@ +import { assert } from '@0xproject/assert'; +import { addressUtils } from '@0xproject/utils'; +import * as lightwallet from 'eth-lightwallet'; +import EthereumTx = require('ethereumjs-tx'); +import * as _ from 'lodash'; + +import { PartialTxParams, WalletSubproviderErrors } from '../types'; + +import { BaseWalletSubprovider } from './base_wallet_subprovider'; + +/* + * This class implements the web3-provider-engine subprovider interface and forwards + * requests involving user accounts and signing operations to eth-lightwallet + * + * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js + */ +export class EthLightwalletSubprovider extends BaseWalletSubprovider { + private _signing: any; + private _keystore: any; + private _pwDerivedKey: Uint8Array; + + constructor(signing: lightwallet.signing, keystore: lightwallet.keystore, pwDerivedKey: Uint8Array) { + super(); + + this._signing = signing; + this._keystore = keystore; + this._pwDerivedKey = pwDerivedKey; + } + + /** + * Retrieve the accounts associated with the eth-lightwallet instance. + * This method is implicitly called when issuing a `eth_accounts` JSON RPC request + * via your providerEngine instance. + * + * @return An array of accounts + */ + public async getAccountsAsync(): Promise { + const accounts = this._keystore.getAddresses(); + return accounts; + } + + /** + * Signs a transaction with the account specificed by the `from` field in txParams. + * If you've added this Subprovider to your app's provider, you can simply send + * an `eth_sendTransaction` JSON RPC request, and this method will be called auto-magically. + * If you are not using this via a ProviderEngine instance, you can call it directly. + * @param txParams Parameters of the transaction to sign + * @return Signed transaction hex string + */ + public async signTransactionAsync(txParams: PartialTxParams): Promise { + if (_.isUndefined(txParams.from) || !addressUtils.isAddress(txParams.from)) { + throw new Error(WalletSubproviderErrors.FromAddressMissingOrInvalid); + } + + const tx = new EthereumTx(txParams); + const txHex = tx.serialize().toString('hex'); + let signedTxHex: string = this._signing.signTx( + this._keystore, this._pwDerivedKey, txHex, txParams.from, this._keystore.hdPathString); + + signedTxHex = `0x${signedTxHex}`; + + return signedTxHex; + } + + /** + * Sign a personal Ethereum signed message. The signing account will be the account + * associated with the provided address. + * If you've added the MnemonicWalletSubprovider to your app's provider, you can simply send an `eth_sign` + * or `personal_sign` JSON RPC request, and this method will be called auto-magically. + * If you are not using this via a ProviderEngine instance, you can call it directly. + * @param data Hex string message to sign + * @param address Address of the account to sign with + * @return Signature hex string (order: rsv) + */ + public async signPersonalMessageAsync(data: string, address: string): Promise { + if (_.isUndefined(data)) { + throw new Error(WalletSubproviderErrors.DataMissingForSignPersonalMessage); + } + assert.isHexString('data', data); + assert.isETHAddressHex('address', address); + const result: ECSignatureBuffer = await this._signing.signMsgHash( + this._keystore, this._pwDerivedKey, data, address, this._keystore.hdPathString); + + const signature = this._signing.concatSig(result); + + return signature; + } +} diff --git a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts index 762163338..51308b6c2 100644 --- a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts +++ b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts @@ -67,10 +67,8 @@ describe('EthLightwalletSubprovider', () => { // Keccak-256 hash of 'hello world' const messageHash = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'; - const ecSignatureHex = await ethLightwalletSubprovider.signPersonalMessageAsync( - messageHash, - signingAccount, - ); + const ecSignatureHex = + await ethLightwalletSubprovider.signPersonalMessageAsync(messageHash, signingAccount); expect(ecSignatureHex).to.be.equal( // tslint:disable-next-line:max-line-length '0xa46b696c1aa8f91dbb33d1a66f6440bf3cf334c9dc45dc389668c1e60e2db31e259400b41f31632fa994837054c5345c88dc455c13931332489029adee6fd24d1b', -- cgit v1.2.3 From 87d66ccf6cad43b58a3064dcc3a7e66eced84f66 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 25 Jun 2018 22:58:36 +0200 Subject: Fix Tslint issues --- packages/contract-wrappers/src/utils/decorators.ts | 8 +++--- .../src/utils/exchange_transfer_simulator.ts | 3 +- .../contract-wrappers/src/utils/filter_utils.ts | 4 +-- .../test/ether_token_wrapper_test.ts | 4 +-- .../test/exchange_wrapper_test.ts | 4 +-- .../contract-wrappers/test/subscription_test.ts | 2 +- .../contract-wrappers/test/token_wrapper_test.ts | 4 +-- .../src/order_watcher/order_watcher.ts | 33 ++++++---------------- .../test/unit/eth_lightwallet_subprovider_test.ts | 10 +++++-- 9 files changed, 31 insertions(+), 41 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/src/utils/decorators.ts b/packages/contract-wrappers/src/utils/decorators.ts index 494575e7b..ccb4c6e11 100644 --- a/packages/contract-wrappers/src/utils/decorators.ts +++ b/packages/contract-wrappers/src/utils/decorators.ts @@ -30,8 +30,8 @@ const schemaErrorTransformer = (error: Error) => { */ const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => { const asyncErrorHandlingDecorator = ( - target: object, - key: string | symbol, + _target: object, + _key: string | symbol, descriptor: TypedPropertyDescriptor, ) => { const originalMethod = descriptor.value as AsyncMethod; @@ -57,8 +57,8 @@ const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => { const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => { const syncErrorHandlingDecorator = ( - target: object, - key: string | symbol, + _target: object, + _key: string | symbol, descriptor: TypedPropertyDescriptor, ) => { const originalMethod = descriptor.value as SyncMethod; diff --git a/packages/contract-wrappers/src/utils/exchange_transfer_simulator.ts b/packages/contract-wrappers/src/utils/exchange_transfer_simulator.ts index 527b8575d..279f2a796 100644 --- a/packages/contract-wrappers/src/utils/exchange_transfer_simulator.ts +++ b/packages/contract-wrappers/src/utils/exchange_transfer_simulator.ts @@ -1,8 +1,7 @@ -import { BlockParamLiteral, ExchangeContractErrs } from '@0xproject/types'; +import { ExchangeContractErrs } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import { AbstractBalanceAndProxyAllowanceLazyStore } from '../abstract/abstract_balance_and_proxy_allowance_lazy_store'; -import { TokenWrapper } from '../contract_wrappers/token_wrapper'; import { TradeSide, TransferType } from '../types'; import { constants } from '../utils/constants'; diff --git a/packages/contract-wrappers/src/utils/filter_utils.ts b/packages/contract-wrappers/src/utils/filter_utils.ts index 5256d010f..f96dc573f 100644 --- a/packages/contract-wrappers/src/utils/filter_utils.ts +++ b/packages/contract-wrappers/src/utils/filter_utils.ts @@ -30,7 +30,7 @@ export const filterUtils = { blockRange?: BlockRange, ): FilterObject { const eventAbi = _.find(abi, { name: eventName }) as EventAbi; - const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi, eventName); + const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi); const topicForEventSignature = ethUtil.addHexPrefix(jsSHA3.keccak256(eventSignature)); const topicsForIndexedArgs = filterUtils.getTopicsForIndexedArgs(eventAbi, indexFilterValues); const topics = [topicForEventSignature, ...topicsForIndexedArgs]; @@ -46,7 +46,7 @@ export const filterUtils = { } return filter; }, - getEventSignatureFromAbiByName(eventAbi: EventAbi, eventName: ContractEvents): string { + getEventSignatureFromAbiByName(eventAbi: EventAbi): string { const types = _.map(eventAbi.inputs, 'type'); const signature = `${eventAbi.name}(${types.join(',')})`; return signature; diff --git a/packages/contract-wrappers/test/ether_token_wrapper_test.ts b/packages/contract-wrappers/test/ether_token_wrapper_test.ts index b13ac72bb..f401ef90a 100644 --- a/packages/contract-wrappers/test/ether_token_wrapper_test.ts +++ b/packages/contract-wrappers/test/ether_token_wrapper_test.ts @@ -277,7 +277,7 @@ describe('EtherTokenWrapper', () => { it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent) => { + (_logEvent: DecodedLogEvent) => { done(new Error('Expected this subscription to have been cancelled')); }, ); @@ -307,7 +307,7 @@ describe('EtherTokenWrapper', () => { it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent) => { + (_logEvent: DecodedLogEvent) => { done(new Error('Expected this subscription to have been cancelled')); }, ); diff --git a/packages/contract-wrappers/test/exchange_wrapper_test.ts b/packages/contract-wrappers/test/exchange_wrapper_test.ts index cf69d4813..c945b4c70 100644 --- a/packages/contract-wrappers/test/exchange_wrapper_test.ts +++ b/packages/contract-wrappers/test/exchange_wrapper_test.ts @@ -999,7 +999,7 @@ describe('ExchangeWrapper', () => { it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent) => { + (_logEvent: DecodedLogEvent) => { done(new Error('Expected this subscription to have been cancelled')); }, ); @@ -1024,7 +1024,7 @@ describe('ExchangeWrapper', () => { it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent) => { + (_logEvent: DecodedLogEvent) => { done(new Error('Expected this subscription to have been cancelled')); }, ); diff --git a/packages/contract-wrappers/test/subscription_test.ts b/packages/contract-wrappers/test/subscription_test.ts index 4d638bf9b..b9417ca3d 100644 --- a/packages/contract-wrappers/test/subscription_test.ts +++ b/packages/contract-wrappers/test/subscription_test.ts @@ -80,7 +80,7 @@ describe('SubscriptionTest', () => { }); it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => { (async () => { - const callback = (err: Error | null, logEvent?: DecodedLogEvent) => _.noop; + const callback = (_err: Error | null, _logEvent?: DecodedLogEvent) => _.noop; contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback); stubs = [ Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws( diff --git a/packages/contract-wrappers/test/token_wrapper_test.ts b/packages/contract-wrappers/test/token_wrapper_test.ts index c9722c7b4..86b93b3f9 100644 --- a/packages/contract-wrappers/test/token_wrapper_test.ts +++ b/packages/contract-wrappers/test/token_wrapper_test.ts @@ -484,7 +484,7 @@ describe('TokenWrapper', () => { it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent) => { + (_logEvent: DecodedLogEvent) => { done(new Error('Expected this subscription to have been cancelled')); }, ); @@ -508,7 +508,7 @@ describe('TokenWrapper', () => { it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent) => { + (_logEvent: DecodedLogEvent) => { done(new Error('Expected this subscription to have been cancelled')); }, ); diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index 140aa341b..d0acf2e6b 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -19,24 +19,9 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import { artifacts } from '../artifacts'; -import { - DepositContractEventArgs, - EtherTokenContractEventArgs, - EtherTokenEvents, - WithdrawalContractEventArgs, -} from '../generated_contract_wrappers/ether_token'; -import { - ExchangeContractEventArgs, - ExchangeEvents, - LogCancelContractEventArgs, - LogFillContractEventArgs, -} from '../generated_contract_wrappers/exchange'; -import { - ApprovalContractEventArgs, - TokenContractEventArgs, - TokenEvents, - TransferContractEventArgs, -} from '../generated_contract_wrappers/token'; +import { EtherTokenContractEventArgs, EtherTokenEvents } from '../generated_contract_wrappers/ether_token'; +import { ExchangeContractEventArgs, ExchangeEvents } from '../generated_contract_wrappers/exchange'; +import { TokenContractEventArgs, TokenEvents } from '../generated_contract_wrappers/token'; import { OnOrderStateChangeCallback, OrderWatcherConfig, OrderWatcherError } from '../types'; import { assert } from '../utils/assert'; @@ -252,7 +237,7 @@ export class OrderWatcher { switch (decodedLog.event) { case TokenEvents.Approval: { // Invalidate cache - const args = decodedLog.args as ApprovalContractEventArgs; + const args = decodedLog.args; this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; @@ -268,7 +253,7 @@ export class OrderWatcher { } case TokenEvents.Transfer: { // Invalidate cache - const args = decodedLog.args as TransferContractEventArgs; + const args = decodedLog.args; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._from); this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._to); // Revalidate orders @@ -285,7 +270,7 @@ export class OrderWatcher { } case EtherTokenEvents.Deposit: { // Invalidate cache - const args = decodedLog.args as DepositContractEventArgs; + const args = decodedLog.args; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; @@ -301,7 +286,7 @@ export class OrderWatcher { } case EtherTokenEvents.Withdrawal: { // Invalidate cache - const args = decodedLog.args as WithdrawalContractEventArgs; + const args = decodedLog.args; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; @@ -317,7 +302,7 @@ export class OrderWatcher { } case ExchangeEvents.LogFill: { // Invalidate cache - const args = decodedLog.args as LogFillContractEventArgs; + const args = decodedLog.args; this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash); // Revalidate orders const orderHash = args.orderHash; @@ -329,7 +314,7 @@ export class OrderWatcher { } case ExchangeEvents.LogCancel: { // Invalidate cache - const args = decodedLog.args as LogCancelContractEventArgs; + const args = decodedLog.args; this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash); // Revalidate orders const orderHash = args.orderHash; diff --git a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts index 51308b6c2..77a1ac58e 100644 --- a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts +++ b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts @@ -33,6 +33,9 @@ describe('EthLightwalletSubprovider', () => { return new Promise(resolve => { // Create Vault lightwallet.keystore.createVault(vaultOptions, (err: Error, vaultKeystore) => { + if (err) { + throw new Error(`Failed to createVault: ${err}`); + } resolve(vaultKeystore); }); }); @@ -41,6 +44,9 @@ describe('EthLightwalletSubprovider', () => { const deriveKeyFromPasswordAsync = async (vaultKeystore: lightwallet.keystore) => { return new Promise(resolve => { vaultKeystore.keyFromPassword(PASSWORD, (err: Error, passwordDerivedKey: Uint8Array) => { + if (err) { + throw new Error(`Failed to get key from password: ${err}`); + } resolve(passwordDerivedKey); }); }); @@ -154,7 +160,7 @@ describe('EthLightwalletSubprovider', () => { params: ['0x0000000000000000000000000000000000000000', nonHexMessage], id: 1, }; - const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { + const callback = reportCallbackErrors(done)((err: Error, _response: JSONRPCResponsePayload) => { expect(err).to.not.be.a('null'); expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world'); done(); @@ -169,7 +175,7 @@ describe('EthLightwalletSubprovider', () => { params: [nonHexMessage, '0x0000000000000000000000000000000000000000'], id: 1, }; - const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { + const callback = reportCallbackErrors(done)((err: Error, _response: JSONRPCResponsePayload) => { expect(err).to.not.be.a('null'); expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world'); done(); -- cgit v1.2.3 From 1dd9ec4d5af3de37a9f7defd11265795d04c9604 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 25 Jun 2018 22:58:50 +0200 Subject: Remove duplicate type --- packages/subproviders/src/globals.d.ts | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'packages') diff --git a/packages/subproviders/src/globals.d.ts b/packages/subproviders/src/globals.d.ts index 1e104053f..287d5e0fe 100644 --- a/packages/subproviders/src/globals.d.ts +++ b/packages/subproviders/src/globals.d.ts @@ -62,26 +62,3 @@ declare module '*.json' { export default json; /* tslint:enable */ } - -// eth-lightwallet declarations -declare module 'eth-lightwallet' { - export class signing { - public static signTx(keystore: keystore, pwDerivedKey: Uint8Array, rawTx: string, signingAddress: string): string; - public static signMsg(keystore: keystore, pwDerivedKey: Uint8Array, rawMsg: string, signingAddress: string): ECSignatureBuffer; - public static signMsgHash(keystore: keystore, pwDerivedKey: Uint8Array, msgHash: string, signingAddress: string): ECSignatureBuffer; - public static concatSig(signature: any): string; - } - export class keystore { - public static createVault(options: any, callback?: (error: Error, keystore: keystore) => void): keystore; - public static generateRandomSeed(): string; - public static isSeedValid(seed: string): boolean; - public static deserialize(keystore: string): keystore; - public serialize(): string; - public keyFromPassword(password: string, callback?: (error: Error, pwDerivedKey: Uint8Array) => void): Uint8Array; - public isDerivedKeyCorrect(pwDerivedKey: Uint8Array): boolean; - public generateNewAddress(pwDerivedKey: Uint8Array, numberOfAddresses: number): void; - public getSeed(pwDerivedKey: Uint8Array): string; - public exportPrivateKey(address: string, pwDerivedKey: Uint8Array): string; - public getAddresses(): string[]; - } -} -- cgit v1.2.3 From 699de9174e242a81c469a14319c2384b94e47356 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 25 Jun 2018 22:59:04 +0200 Subject: Format type --- .../types/eth-lightwallet/index.d.ts | 67 +++++++++++++++------- 1 file changed, 47 insertions(+), 20 deletions(-) (limited to 'packages') diff --git a/packages/typescript-typings/types/eth-lightwallet/index.d.ts b/packages/typescript-typings/types/eth-lightwallet/index.d.ts index 76f910d9c..f6d0cd6d8 100644 --- a/packages/typescript-typings/types/eth-lightwallet/index.d.ts +++ b/packages/typescript-typings/types/eth-lightwallet/index.d.ts @@ -1,24 +1,51 @@ // eth-lightwallet declarations declare module 'eth-lightwallet' { - import { ECSignatureBuffer } from "@0xproject/types"; + import { ECSignatureBuffer } from '@0xproject/types'; - export class signing { - public static signTx(keystore: keystore, pwDerivedKey: Uint8Array, rawTx: string, signingAddress: string): string; - public static signMsg(keystore: keystore, pwDerivedKey: Uint8Array, rawMsg: string, signingAddress: string): ECSignatureBuffer; - public static signMsgHash(keystore: keystore, pwDerivedKey: Uint8Array, msgHash: string, signingAddress: string): ECSignatureBuffer; - public static concatSig(signature: any): string; - } - export class keystore { - public static createVault(options: any, callback?: (error: Error, keystore: keystore) => void): keystore; - public static generateRandomSeed(): string; - public static isSeedValid(seed: string): boolean; - public static deserialize(keystore: string): keystore; - public serialize(): string; - public keyFromPassword(password: string, callback?: (error: Error, pwDerivedKey: Uint8Array) => void): Uint8Array; - public isDerivedKeyCorrect(pwDerivedKey: Uint8Array): boolean; - public generateNewAddress(pwDerivedKey: Uint8Array, numberOfAddresses: number): void; - public getSeed(pwDerivedKey: Uint8Array): string; - public exportPrivateKey(address: string, pwDerivedKey: Uint8Array): string; - public getAddresses(): string[]; - } + // tslint:disable-next-line:class-name + export class signing { + public static signTx( + keystore: keystore, + pwDerivedKey: Uint8Array, + rawTx: string, + signingAddress: string, + ): string; + public static signMsg( + keystore: keystore, + pwDerivedKey: Uint8Array, + rawMsg: string, + signingAddress: string, + ): ECSignatureBuffer; + public static signMsgHash( + keystore: keystore, + pwDerivedKey: Uint8Array, + msgHash: string, + signingAddress: string, + ): ECSignatureBuffer; + public static concatSig(signature: any): string; + } + // tslint:disable-next-line:class-name + export class keystore { + public static createVault(options: any, callback?: (error: Error, keystore: keystore) => void): keystore; + public static generateRandomSeed(): string; + public static isSeedValid(seed: string): boolean; + public static deserialize(keystore: string): keystore; + public serialize(): string; + public keyFromPassword( + password: string, + callback?: (error: Error, pwDerivedKey: Uint8Array) => void, + ): Uint8Array; + public isDerivedKeyCorrect(pwDerivedKey: Uint8Array): boolean; + public generateNewAddress(pwDerivedKey: Uint8Array, numberOfAddresses: number): void; + public getSeed(pwDerivedKey: Uint8Array): string; + public exportPrivateKey(address: string, pwDerivedKey: Uint8Array): string; + public getAddresses(): string[]; + } + + interface VaultOptions { + password: string; + seedPhrase: string; + salt?: string; + hdPathString: string; + } } -- cgit v1.2.3 From b2e32aaf588196b21a453fe7f7e38eb6eb154c22 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 25 Jun 2018 22:59:24 +0200 Subject: Remove legacy named subprovider --- .../src/subproviders/eth_lightwallet.ts | 100 --------------------- 1 file changed, 100 deletions(-) delete mode 100644 packages/subproviders/src/subproviders/eth_lightwallet.ts (limited to 'packages') diff --git a/packages/subproviders/src/subproviders/eth_lightwallet.ts b/packages/subproviders/src/subproviders/eth_lightwallet.ts deleted file mode 100644 index 970c5d981..000000000 --- a/packages/subproviders/src/subproviders/eth_lightwallet.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { assert } from '@0xproject/assert'; -import { ECSignatureBuffer } from '@0xproject/types'; -import { addressUtils } from '@0xproject/utils'; -import * as lightwallet from 'eth-lightwallet'; -import EthereumTx = require('ethereumjs-tx'); -import * as _ from 'lodash'; - -import { PartialTxParams, WalletSubproviderErrors } from '../types'; - -import { BaseWalletSubprovider } from './base_wallet_subprovider'; - -/* - * This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) subprovider interface. - * This subprovider intercepts all account related RPC requests (e.g message/transaction signing, etc...) and - * re-routes them to [eth-lightwallet](https://github.com/ConsenSys/eth-lightwallet). - */ -export class EthLightwalletSubprovider extends BaseWalletSubprovider { - private _signing: lightwallet.signing; - private _keystore: lightwallet.keystore; - private _pwDerivedKey: Uint8Array; - /** - * Instantiates a EthLightwalletSubprovider - * @param signing The lightwallet module containing signing functions - * @param keystore An instance of the lightwallet keystore - * @param pwDerivedKey The users password derived key - */ - constructor(signing: lightwallet.signing, keystore: lightwallet.keystore, pwDerivedKey: Uint8Array) { - super(); - - this._signing = signing; - this._keystore = keystore; - this._pwDerivedKey = pwDerivedKey; - } - /** - * Retrieve the accounts associated with the eth-lightwallet instance. - * This method is implicitly called when issuing a `eth_accounts` JSON RPC request - * via your providerEngine instance. - * - * @return An array of accounts - */ - public async getAccountsAsync(): Promise { - const accounts = this._keystore.getAddresses(); - return accounts; - } - /** - * Signs a transaction with the account specificed by the `from` field in txParams. - * If you've added this Subprovider to your app's provider, you can simply send - * an `eth_sendTransaction` JSON RPC request, and this method will be called auto-magically. - * If you are not using this via a ProviderEngine instance, you can call it directly. - * @param txParams Parameters of the transaction to sign - * @return Signed transaction hex string - */ - public async signTransactionAsync(txParams: PartialTxParams): Promise { - if (_.isUndefined(txParams.from) || !addressUtils.isAddress(txParams.from)) { - throw new Error(WalletSubproviderErrors.FromAddressMissingOrInvalid); - } - - const tx = new EthereumTx(txParams); - const txHex = tx.serialize().toString('hex'); - let signedTxHex: string = this._signing.signTx( - this._keystore, - this._pwDerivedKey, - txHex, - txParams.from, - this._keystore.hdPathString, - ); - - signedTxHex = `0x${signedTxHex}`; - - return signedTxHex; - } - /** - * Sign a personal Ethereum signed message. The signing account will be the account - * associated with the provided address. - * If you've added the EthLightwalletSubprovider to your app's provider, you can simply send an `eth_sign` - * or `personal_sign` JSON RPC request, and this method will be called auto-magically. - * If you are not using this via a ProviderEngine instance, you can call it directly. - * @param data Hex string message to sign - * @param address Address of the account to sign with - * @return Signature hex string (order: rsv) - */ - public async signPersonalMessageAsync(data: string, address: string): Promise { - if (_.isUndefined(data)) { - throw new Error(WalletSubproviderErrors.DataMissingForSignPersonalMessage); - } - assert.isHexString('data', data); - assert.isETHAddressHex('address', address); - const result: ECSignatureBuffer = await this._signing.signMsgHash( - this._keystore, - this._pwDerivedKey, - data, - address, - this._keystore.hdPathString, - ); - - const signature = this._signing.concatSig(result); - - return signature; - } -} -- cgit v1.2.3 From 31e3b9ff8baac145be3e00eedc6d0ae065474b8d Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 25 Jun 2018 22:59:41 +0200 Subject: Fix and imprrove ethLightWalletSubprovider --- packages/subproviders/package.json | 2 +- .../src/subproviders/eth_lightwallet_subprovider.ts | 19 ++++++++++--------- .../test/unit/eth_lightwallet_subprovider_test.ts | 11 ++++++----- 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'packages') diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index c3e588718..76b88cee0 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "@0xproject/assert": "^0.2.12", - "@0xproject/types": "^0.8.1", + "@0xproject/types": "^1.0.0", "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", "@ledgerhq/hw-app-eth": "^4.3.0", diff --git a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts index 7507eeb49..a908ab5fc 100644 --- a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts +++ b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts @@ -15,14 +15,12 @@ import { BaseWalletSubprovider } from './base_wallet_subprovider'; * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js */ export class EthLightwalletSubprovider extends BaseWalletSubprovider { - private _signing: any; - private _keystore: any; + private _keystore: lightwallet.keystore; private _pwDerivedKey: Uint8Array; - constructor(signing: lightwallet.signing, keystore: lightwallet.keystore, pwDerivedKey: Uint8Array) { + constructor(keystore: lightwallet.keystore, pwDerivedKey: Uint8Array) { super(); - this._signing = signing; this._keystore = keystore; this._pwDerivedKey = pwDerivedKey; } @@ -54,8 +52,7 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { const tx = new EthereumTx(txParams); const txHex = tx.serialize().toString('hex'); - let signedTxHex: string = this._signing.signTx( - this._keystore, this._pwDerivedKey, txHex, txParams.from, this._keystore.hdPathString); + let signedTxHex: string = lightwallet.signing.signTx(this._keystore, this._pwDerivedKey, txHex, txParams.from); signedTxHex = `0x${signedTxHex}`; @@ -78,10 +75,14 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { } assert.isHexString('data', data); assert.isETHAddressHex('address', address); - const result: ECSignatureBuffer = await this._signing.signMsgHash( - this._keystore, this._pwDerivedKey, data, address, this._keystore.hdPathString); + const result: ECSignatureBuffer = lightwallet.signing.signMsgHash( + this._keystore, + this._pwDerivedKey, + data, + address, + ); - const signature = this._signing.concatSig(result); + const signature = lightwallet.signing.concatSig(result); return signature; } diff --git a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts index 77a1ac58e..b99dbff2f 100644 --- a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts +++ b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts @@ -1,8 +1,7 @@ -import { JSONRPCResponsePayload } from '@0xproject/types'; import * as chai from 'chai'; import * as lightwallet from 'eth-lightwallet'; +import { JSONRPCResponsePayload } from 'ethereum-types'; import Web3ProviderEngine = require('web3-provider-engine'); -import RpcSubprovider = require('web3-provider-engine/subproviders/rpc'); import { EthLightwalletSubprovider } from '../../src'; import { DoneCallback } from '../../src/types'; @@ -59,7 +58,7 @@ describe('EthLightwalletSubprovider', () => { keystore.generateNewAddress(pwDerivedKey, NUM_GENERATED_ADDRESSES); // Initialize Subprovider - ethLightwalletSubprovider = new EthLightwalletSubprovider(lightwallet.signing, keystore, pwDerivedKey); + ethLightwalletSubprovider = new EthLightwalletSubprovider(keystore, pwDerivedKey); }); describe('direct method calls', () => { describe('success cases', () => { @@ -73,8 +72,10 @@ describe('EthLightwalletSubprovider', () => { // Keccak-256 hash of 'hello world' const messageHash = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'; - const ecSignatureHex = - await ethLightwalletSubprovider.signPersonalMessageAsync(messageHash, signingAccount); + const ecSignatureHex = await ethLightwalletSubprovider.signPersonalMessageAsync( + messageHash, + signingAccount, + ); expect(ecSignatureHex).to.be.equal( // tslint:disable-next-line:max-line-length '0xa46b696c1aa8f91dbb33d1a66f6440bf3cf334c9dc45dc389668c1e60e2db31e259400b41f31632fa994837054c5345c88dc455c13931332489029adee6fd24d1b', -- cgit v1.2.3 From 6bb2203f790923a83f6f0665d47d29a90817b371 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 25 Jun 2018 23:07:27 +0200 Subject: Small stylistic tweaks --- .../subproviders/src/subproviders/eth_lightwallet_subprovider.ts | 6 ------ packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts | 5 +---- packages/typescript-typings/types/eth-lightwallet/index.d.ts | 1 - 3 files changed, 1 insertion(+), 11 deletions(-) (limited to 'packages') diff --git a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts index a908ab5fc..64d984996 100644 --- a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts +++ b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts @@ -17,14 +17,11 @@ import { BaseWalletSubprovider } from './base_wallet_subprovider'; export class EthLightwalletSubprovider extends BaseWalletSubprovider { private _keystore: lightwallet.keystore; private _pwDerivedKey: Uint8Array; - constructor(keystore: lightwallet.keystore, pwDerivedKey: Uint8Array) { super(); - this._keystore = keystore; this._pwDerivedKey = pwDerivedKey; } - /** * Retrieve the accounts associated with the eth-lightwallet instance. * This method is implicitly called when issuing a `eth_accounts` JSON RPC request @@ -36,7 +33,6 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { const accounts = this._keystore.getAddresses(); return accounts; } - /** * Signs a transaction with the account specificed by the `from` field in txParams. * If you've added this Subprovider to your app's provider, you can simply send @@ -58,7 +54,6 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { return signedTxHex; } - /** * Sign a personal Ethereum signed message. The signing account will be the account * associated with the provided address. @@ -83,7 +78,6 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { ); const signature = lightwallet.signing.concatSig(result); - return signature; } } diff --git a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts index b99dbff2f..c0adb9225 100644 --- a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts +++ b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts @@ -11,6 +11,7 @@ import { reportCallbackErrors } from '../utils/report_callback_errors'; chaiSetup.configure(); const expect = chai.expect; + const FAKE_ADDRESS = '0x44be42fd88e22387c43ba9b75941aa3e680dae25'; const NUM_GENERATED_ADDRESSES = 10; const PASSWORD = 'supersecretpassword99'; @@ -30,7 +31,6 @@ describe('EthLightwalletSubprovider', () => { const createVaultAsync = async (vaultOptions: lightwallet.VaultOptions) => { return new Promise(resolve => { - // Create Vault lightwallet.keystore.createVault(vaultOptions, (err: Error, vaultKeystore) => { if (err) { throw new Error(`Failed to createVault: ${err}`); @@ -39,7 +39,6 @@ describe('EthLightwalletSubprovider', () => { }); }); }; - const deriveKeyFromPasswordAsync = async (vaultKeystore: lightwallet.keystore) => { return new Promise(resolve => { vaultKeystore.keyFromPassword(PASSWORD, (err: Error, passwordDerivedKey: Uint8Array) => { @@ -50,14 +49,12 @@ describe('EthLightwalletSubprovider', () => { }); }); }; - const keystore: lightwallet.keystore = await createVaultAsync(options); const pwDerivedKey: Uint8Array = await deriveKeyFromPasswordAsync(keystore); // Generate 10 addresses keystore.generateNewAddress(pwDerivedKey, NUM_GENERATED_ADDRESSES); - // Initialize Subprovider ethLightwalletSubprovider = new EthLightwalletSubprovider(keystore, pwDerivedKey); }); describe('direct method calls', () => { diff --git a/packages/typescript-typings/types/eth-lightwallet/index.d.ts b/packages/typescript-typings/types/eth-lightwallet/index.d.ts index f6d0cd6d8..58096e9f4 100644 --- a/packages/typescript-typings/types/eth-lightwallet/index.d.ts +++ b/packages/typescript-typings/types/eth-lightwallet/index.d.ts @@ -41,7 +41,6 @@ declare module 'eth-lightwallet' { public exportPrivateKey(address: string, pwDerivedKey: Uint8Array): string; public getAddresses(): string[]; } - interface VaultOptions { password: string; seedPhrase: string; -- cgit v1.2.3 From 3031598843080ff4fabb7bfb0ba823be6d545285 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sat, 30 Jun 2018 13:23:13 -0700 Subject: Implement icon button --- packages/website/ts/components/ui/text.tsx | 5 +++-- packages/website/ts/components/wallet/wallet.tsx | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/ui/text.tsx b/packages/website/ts/components/ui/text.tsx index c1cb2ade4..315f72854 100644 --- a/packages/website/ts/components/ui/text.tsx +++ b/packages/website/ts/components/ui/text.tsx @@ -3,7 +3,7 @@ import { darken } from 'polished'; import * as React from 'react'; import { styled } from 'ts/style/theme'; -export type TextTag = 'p' | 'div' | 'span' | 'label' | 'h1' | 'h2' | 'h3' | 'h4'; +export type TextTag = 'p' | 'div' | 'span' | 'label' | 'h1' | 'h2' | 'h3' | 'h4' | 'i'; export interface TextProps { className?: string; @@ -17,6 +17,7 @@ export interface TextProps { fontWeight?: number | string; textDecorationLine?: string; onClick?: (event: React.MouseEvent) => void; + hoverColor?: string; } const PlainText: React.StatelessComponent = ({ children, className, onClick, Tag }) => ( @@ -37,7 +38,7 @@ export const Text = styled(PlainText)` ${props => (props.onClick ? 'cursor: pointer' : '')}; transition: color 0.5s ease; &:hover { - ${props => (props.onClick ? `color: ${darken(0.3, props.fontColor)}` : '')}; + ${props => (props.onClick ? `color: ${props.hoverColor || darken(0.3, props.fontColor)}` : '')}; } `; diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 1f1e3598a..899f8e3a3 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -199,11 +199,26 @@ export class Wallet extends React.Component { ); + const onClick = _.noop; + const accessory = ( + + + + ); return ( } main={main} + accessory={accessory} minHeight="60px" backgroundColor={colors.white} /> -- cgit v1.2.3 From be64184cfa11dcabd543161b5d7a6726d4e7924d Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sat, 30 Jun 2018 13:51:40 -0700 Subject: Clean up a bit of the provider display logic --- .../ts/components/top_bar/install_prompt.tsx | 59 ++++++++++++++ .../ts/components/top_bar/provider_display.tsx | 92 +++++----------------- packages/website/ts/components/ui/drop_down.tsx | 2 +- 3 files changed, 80 insertions(+), 73 deletions(-) create mode 100644 packages/website/ts/components/top_bar/install_prompt.tsx (limited to 'packages') diff --git a/packages/website/ts/components/top_bar/install_prompt.tsx b/packages/website/ts/components/top_bar/install_prompt.tsx new file mode 100644 index 000000000..8d1a9c48a --- /dev/null +++ b/packages/website/ts/components/top_bar/install_prompt.tsx @@ -0,0 +1,59 @@ +import RaisedButton from 'material-ui/RaisedButton'; +import * as React from 'react'; + +import { colors } from 'ts/style/colors'; +import { constants } from 'ts/utils/constants'; + +export interface InstallPromptProps { + onToggleLedgerDialog: () => void; +} + +export const InstallPrompt: React.StatelessComponent = ({ onToggleLedgerDialog }) => { + return ( +
+
+ Choose a wallet: +
+
+
+
Install a browser wallet
+
+ +
+ +
+
+
+
or
+
+
+
+
Connect to a ledger hardware wallet
+
+ +
+
+ +
+
+
+
+ ); +}; diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 8743e4320..18afee4ea 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -7,6 +7,7 @@ import Lock from 'material-ui/svg-icons/action/lock'; import * as React from 'react'; import { Blockchain } from 'ts/blockchain'; +import { InstallPrompt } from 'ts/components/top_bar/install_prompt'; import { ProviderPicker } from 'ts/components/top_bar/provider_picker'; import { AccountConnection } from 'ts/components/ui/account_connection'; import { Container } from 'ts/components/ui/container'; @@ -72,78 +73,25 @@ export class ProviderDisplay extends React.Component - ); - } else { - // Nothing to connect to, show install/info popover - return ( -
-
- Choose a wallet: -
-
-
-
Install a browser wallet
-
- -
-
- Use{' '} - - Metamask - {' '} - or{' '} - - Parity Signer - -
-
-
-
-
or
-
-
-
-
Connect to a ledger hardware wallet
-
- -
-
- -
-
-
-
- ); + const accountState = this._getAccountState(); + switch (accountState) { + case AccountState.Ready: + case AccountState.Locked: + return ( + + ); + case AccountState.Disconnected: + return ; + case AccountState.Loading: + default: + return null; } } private _renderIcon(): React.ReactNode { diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index 22cb942f8..7d900d685 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -66,7 +66,7 @@ export class DropDown extends React.Component { targetOrigin={this.props.targetOrigin} onRequestClose={this._closePopover.bind(this)} useLayerForClickAway={false} - animation={PopoverAnimationVertical} + animated={false} zDepth={this.props.zDepth} >
-- cgit v1.2.3 From da8cf9981eda4a068c22d0107e07b704afda2584 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sat, 30 Jun 2018 14:25:33 -0700 Subject: Implement simple menu --- .../ts/components/top_bar/provider_display.tsx | 25 ++++--- .../ts/components/top_bar/provider_picker.tsx | 79 ---------------------- packages/website/ts/components/ui/container.tsx | 1 + packages/website/ts/components/ui/drop_down.tsx | 2 +- packages/website/ts/components/ui/simple_menu.tsx | 34 ++++++++++ 5 files changed, 50 insertions(+), 91 deletions(-) delete mode 100644 packages/website/ts/components/top_bar/provider_picker.tsx create mode 100644 packages/website/ts/components/ui/simple_menu.tsx (limited to 'packages') diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 18afee4ea..3f29d5ff3 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -5,19 +5,21 @@ import RaisedButton from 'material-ui/RaisedButton'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; import Lock from 'material-ui/svg-icons/action/lock'; import * as React from 'react'; +import * as CopyToClipboard from 'react-copy-to-clipboard'; +import { Link } from 'react-router-dom'; import { Blockchain } from 'ts/blockchain'; import { InstallPrompt } from 'ts/components/top_bar/install_prompt'; -import { ProviderPicker } from 'ts/components/top_bar/provider_picker'; import { AccountConnection } from 'ts/components/ui/account_connection'; import { Container } from 'ts/components/ui/container'; import { DropDown } from 'ts/components/ui/drop_down'; import { Identicon } from 'ts/components/ui/identicon'; import { Island } from 'ts/components/ui/island'; +import { SimpleMenu, SimpleMenuItem } from 'ts/components/ui/simple_menu'; import { Text } from 'ts/components/ui/text'; import { Dispatcher } from 'ts/redux/dispatcher'; import { colors } from 'ts/style/colors'; -import { AccountState, ProviderType } from 'ts/types'; +import { AccountState, ProviderType, WebsitePaths } from 'ts/types'; import { constants } from 'ts/utils/constants'; import { utils } from 'ts/utils/utils'; @@ -76,19 +78,20 @@ export class ProviderDisplay extends React.Component + + + + + + + + + ); case AccountState.Disconnected: return ; + case AccountState.Locked: case AccountState.Loading: default: return null; diff --git a/packages/website/ts/components/top_bar/provider_picker.tsx b/packages/website/ts/components/top_bar/provider_picker.tsx deleted file mode 100644 index 7937f2e9d..000000000 --- a/packages/website/ts/components/top_bar/provider_picker.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { colors, constants as sharedConstants } from '@0xproject/react-shared'; -import { RadioButton, RadioButtonGroup } from 'material-ui/RadioButton'; -import * as React from 'react'; -import { Blockchain } from 'ts/blockchain'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { ProviderType } from 'ts/types'; - -interface ProviderPickerProps { - networkId: number; - injectedProviderName: string; - providerType: ProviderType; - onToggleLedgerDialog: () => void; - dispatcher: Dispatcher; - blockchain: Blockchain; -} - -interface ProviderPickerState {} - -export class ProviderPicker extends React.Component { - public render(): React.ReactNode { - const isLedgerSelected = this.props.providerType === ProviderType.Ledger; - const menuStyle = { - padding: 10, - paddingTop: 15, - paddingBottom: 15, - }; - // Show dropdown with two options - return ( -
- - - - -
- ); - } - private _renderLabel(title: string, shouldShowNetwork: boolean): React.ReactNode { - const label = ( -
-
{title}
- {shouldShowNetwork && this._renderNetwork()} -
- ); - return label; - } - private _renderNetwork(): React.ReactNode { - const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId]; - return ( -
-
- -
-
{networkName}
-
- ); - } - private _onProviderRadioChanged(value: string): void { - if (value === ProviderType.Ledger) { - this.props.onToggleLedgerDialog(); - } else { - // tslint:disable-next-line:no-floating-promises - this.props.blockchain.updateProviderToInjectedAsync(); - } - } -} diff --git a/packages/website/ts/components/ui/container.tsx b/packages/website/ts/components/ui/container.tsx index fb718d731..edbf8814b 100644 --- a/packages/website/ts/components/ui/container.tsx +++ b/packages/website/ts/components/ui/container.tsx @@ -17,6 +17,7 @@ export interface ContainerProps { maxHeight?: StringOrNum; width?: StringOrNum; height?: StringOrNum; + minWidth?: StringOrNum; minHeight?: StringOrNum; isHidden?: boolean; className?: string; diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index 7d900d685..3738e50eb 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -49,7 +49,7 @@ export class DropDown extends React.Component { // call hoverOff whenever the dropdown receives updated props. This is a hack // because it will effectively close the dropdown on any prop update, barring // dropdowns from having dynamic content. - this._onHoverOff(); + // this._onHoverOff(); } public render(): React.ReactNode { return ( diff --git a/packages/website/ts/components/ui/simple_menu.tsx b/packages/website/ts/components/ui/simple_menu.tsx new file mode 100644 index 000000000..29445c965 --- /dev/null +++ b/packages/website/ts/components/ui/simple_menu.tsx @@ -0,0 +1,34 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { Container } from 'ts/components/ui/container'; +import { Text } from 'ts/components/ui/text'; +import { colors } from 'ts/style/colors'; + +export interface SimpleMenuProps {} + +export const SimpleMenu: React.StatelessComponent = ({ children }) => { + return ( + + {children} + + ); +}; + +export interface SimpleMenuItemProps { + text: string; + onClick?: () => void; +} +export const SimpleMenuItem: React.StatelessComponent = ({ text, onClick }) => ( + + + {text} + + +); -- cgit v1.2.3 From 6daf754f5bb4aa85d0f65bfdaf8910db4401d1cc Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sat, 30 Jun 2018 23:32:06 -0700 Subject: Add menu to wallet --- packages/website/ts/components/wallet/wallet.tsx | 40 +++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 899f8e3a3..b43164664 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -5,15 +5,18 @@ import * as _ from 'lodash'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; import * as React from 'react'; +import * as CopyToClipboard from 'react-copy-to-clipboard'; import { Link } from 'react-router-dom'; import firstBy = require('thenby'); import { Blockchain } from 'ts/blockchain'; import { AccountConnection } from 'ts/components/ui/account_connection'; import { Container } from 'ts/components/ui/container'; +import { DropDown } from 'ts/components/ui/drop_down'; import { IconButton } from 'ts/components/ui/icon_button'; import { Identicon } from 'ts/components/ui/identicon'; import { Island } from 'ts/components/ui/island'; +import { SimpleMenu, SimpleMenuItem } from 'ts/components/ui/simple_menu'; import { Text } from 'ts/components/ui/text'; import { TokenIcon } from 'ts/components/ui/token_icon'; import { BodyOverlay } from 'ts/components/wallet/body_overlay'; @@ -202,14 +205,35 @@ export class Wallet extends React.Component { const onClick = _.noop; const accessory = ( - + } + popoverContent={ + + + + + + + + + + } + anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} + targetOrigin={{ horizontal: 'right', vertical: 'top' }} + zDepth={1} /> ); -- cgit v1.2.3 From a6f40d418704a8dca8c787663f00b6bcbdf18ba4 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sun, 1 Jul 2018 13:31:43 -0700 Subject: Implement correct behavior for menu in the wallet --- packages/website/ts/blockchain_watcher.ts | 7 +++--- .../ts/components/top_bar/provider_display.tsx | 9 ++++---- packages/website/ts/components/top_bar/top_bar.tsx | 4 ++-- packages/website/ts/components/ui/drop_down.tsx | 27 ++++++++++++++++++---- packages/website/ts/components/ui/simple_menu.tsx | 14 +++++++---- packages/website/ts/components/wallet/wallet.tsx | 22 +++++++++--------- 6 files changed, 52 insertions(+), 31 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/blockchain_watcher.ts b/packages/website/ts/blockchain_watcher.ts index df5f73fd1..4b23aa98a 100644 --- a/packages/website/ts/blockchain_watcher.ts +++ b/packages/website/ts/blockchain_watcher.ts @@ -10,6 +10,7 @@ export class BlockchainWatcher { private _watchBalanceIntervalId: NodeJS.Timer; private _prevUserEtherBalanceInWei?: BigNumber; private _prevUserAddressIfExists: string; + private _prevNodeVersionIfExists: string; constructor(dispatcher: Dispatcher, web3Wrapper: Web3Wrapper, shouldPollUserAddress: boolean) { this._dispatcher = dispatcher; this._shouldPollUserAddress = shouldPollUserAddress; @@ -43,11 +44,9 @@ export class BlockchainWatcher { ); } private async _updateBalanceAsync(): Promise { - let prevNodeVersion: string; - // Check for node version changes const currentNodeVersion = await this._web3Wrapper.getNodeVersionAsync(); - if (currentNodeVersion !== prevNodeVersion) { - prevNodeVersion = currentNodeVersion; + if (this._prevNodeVersionIfExists !== currentNodeVersion) { + this._prevNodeVersionIfExists = currentNodeVersion; this._dispatcher.updateNodeVersion(currentNodeVersion); } diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 3f29d5ff3..6d02ebd59 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -51,7 +51,7 @@ export class ProviderDisplay extends React.Component {this._renderIcon()} @@ -61,14 +61,13 @@ export class ProviderDisplay extends React.Component ); const hasLedgerProvider = this.props.providerType === ProviderType.Ledger; - const horizontalPosition = isExternallyInjectedProvider || hasLedgerProvider ? 'left' : 'middle'; return (
diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index fac6c131f..778536663 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -199,7 +199,7 @@ export class TopBar extends React.Component { cursor: 'pointer', paddingTop: 16, }; - const hoverActiveNode = ( + const activeNode = (
{this.props.translate.get(Key.Developers, Deco.Cap)}
@@ -224,7 +224,7 @@ export class TopBar extends React.Component {
{ public static defaultProps: Partial = { style: DEFAULT_STYLE, zDepth: 1, + shouldWaitForClickToActivate: false, }; private _isHovering: boolean; private _popoverCloseCheckIntervalId: number; @@ -49,7 +51,7 @@ export class DropDown extends React.Component { // call hoverOff whenever the dropdown receives updated props. This is a hack // because it will effectively close the dropdown on any prop update, barring // dropdowns from having dynamic content. - // this._onHoverOff(); + this._onHoverOff(); } public render(): React.ReactNode { return ( @@ -58,7 +60,7 @@ export class DropDown extends React.Component { onMouseEnter={this._onHover.bind(this)} onMouseLeave={this._onHoverOff.bind(this)} > - {this.props.hoverActiveNode} +
{this.props.activeNode}
{ animated={false} zDepth={this.props.zDepth} > -
+
{this.props.popoverContent}
); } + private _onActiveNodeClick(event: React.FormEvent): void { + event.stopPropagation(); + if (this.props.shouldWaitForClickToActivate) { + this.setState({ + isDropDownOpen: true, + anchorEl: event.currentTarget, + }); + } + } private _onHover(event: React.FormEvent): void { this._isHovering = true; - this._checkIfShouldOpenPopover(event); + if (!this.props.shouldWaitForClickToActivate) { + this._checkIfShouldOpenPopover(event); + } } private _checkIfShouldOpenPopover(event: React.FormEvent): void { if (this.state.isDropDownOpen) { diff --git a/packages/website/ts/components/ui/simple_menu.tsx b/packages/website/ts/components/ui/simple_menu.tsx index 29445c965..22414d101 100644 --- a/packages/website/ts/components/ui/simple_menu.tsx +++ b/packages/website/ts/components/ui/simple_menu.tsx @@ -5,15 +5,17 @@ import { Container } from 'ts/components/ui/container'; import { Text } from 'ts/components/ui/text'; import { colors } from 'ts/style/colors'; -export interface SimpleMenuProps {} +export interface SimpleMenuProps { + minWidth?: number | string; +} -export const SimpleMenu: React.StatelessComponent = ({ children }) => { +export const SimpleMenu: React.StatelessComponent = ({ children, minWidth }) => { return ( {children} @@ -26,9 +28,13 @@ export interface SimpleMenuItemProps { onClick?: () => void; } export const SimpleMenuItem: React.StatelessComponent = ({ text, onClick }) => ( - + {text} ); + +SimpleMenu.defaultProps = { + minWidth: '220px', +}; diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index b43164664..fca6c5745 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -206,7 +206,7 @@ export class Wallet extends React.Component { const accessory = ( { /> } popoverContent={ - + @@ -234,19 +234,19 @@ export class Wallet extends React.Component { anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} targetOrigin={{ horizontal: 'right', vertical: 'top' }} zDepth={1} + shouldWaitForClickToActivate={true} /> ); return ( - - } - main={main} - accessory={accessory} - minHeight="60px" - backgroundColor={colors.white} - /> - + } + main={main} + accessory={accessory} + minHeight="60px" + backgroundColor={colors.white} + /> ); } private _renderBody(): React.ReactElement<{}> { -- cgit v1.2.3 From 955fdf5d13945fc7267e8ce0cc1f6016c57f3b72 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sun, 1 Jul 2018 14:03:07 -0700 Subject: Give connected header accessory more padding --- packages/website/ts/components/wallet/wallet.tsx | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index fca6c5745..ab234ae1b 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -207,15 +207,19 @@ export class Wallet extends React.Component { + // this container gives the menu button more of a hover target for the drop down + // it prevents accidentally closing the menu by moving off of the button + + + } popoverContent={ -- cgit v1.2.3 From 5a7908984e118f2babf7c0680bf17afa148f5122 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sun, 1 Jul 2018 14:34:50 -0700 Subject: Consolidate logic for common menu items --- .../ts/components/top_bar/provider_display.tsx | 19 +++---- packages/website/ts/components/ui/simple_menu.tsx | 66 ++++++++++++++++++---- packages/website/ts/components/wallet/wallet.tsx | 22 +++----- 3 files changed, 74 insertions(+), 33 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 6d02ebd59..c2915f9a9 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -5,8 +5,6 @@ import RaisedButton from 'material-ui/RaisedButton'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; import Lock from 'material-ui/svg-icons/action/lock'; import * as React from 'react'; -import * as CopyToClipboard from 'react-copy-to-clipboard'; -import { Link } from 'react-router-dom'; import { Blockchain } from 'ts/blockchain'; import { InstallPrompt } from 'ts/components/top_bar/install_prompt'; @@ -15,7 +13,12 @@ import { Container } from 'ts/components/ui/container'; import { DropDown } from 'ts/components/ui/drop_down'; import { Identicon } from 'ts/components/ui/identicon'; import { Island } from 'ts/components/ui/island'; -import { SimpleMenu, SimpleMenuItem } from 'ts/components/ui/simple_menu'; +import { + CopyAddressSimpleMenuItem, + DifferentWalletSimpleMenuItem, + GoToAccountManagementSimpleMenuItem, + SimpleMenu, +} from 'ts/components/ui/simple_menu'; import { Text } from 'ts/components/ui/text'; import { Dispatcher } from 'ts/redux/dispatcher'; import { colors } from 'ts/style/colors'; @@ -79,13 +82,9 @@ export class ProviderDisplay extends React.Component - - - - - - - + + + ); case AccountState.Disconnected: diff --git a/packages/website/ts/components/ui/simple_menu.tsx b/packages/website/ts/components/ui/simple_menu.tsx index 22414d101..52d97b1ea 100644 --- a/packages/website/ts/components/ui/simple_menu.tsx +++ b/packages/website/ts/components/ui/simple_menu.tsx @@ -1,9 +1,12 @@ import * as _ from 'lodash'; import * as React from 'react'; +import * as CopyToClipboard from 'react-copy-to-clipboard'; +import { Link } from 'react-router-dom'; import { Container } from 'ts/components/ui/container'; import { Text } from 'ts/components/ui/text'; import { colors } from 'ts/style/colors'; +import { WebsitePaths } from 'ts/types'; export interface SimpleMenuProps { minWidth?: number | string; @@ -23,18 +26,61 @@ export const SimpleMenu: React.StatelessComponent = ({ children ); }; +SimpleMenu.defaultProps = { + minWidth: '220px', +}; + export interface SimpleMenuItemProps { - text: string; + displayText: string; onClick?: () => void; } -export const SimpleMenuItem: React.StatelessComponent = ({ text, onClick }) => ( - - - {text} - - -); +export const SimpleMenuItem: React.StatelessComponent = ({ displayText, onClick }) => { + // Falling back to _.noop for onclick retains the hovering effect + return ( + + + {displayText} + + + ); +}; -SimpleMenu.defaultProps = { - minWidth: '220px', +export interface CopyAddressSimpleMenuItemProps { + userAddress: string; + onClick?: () => void; +} +export const CopyAddressSimpleMenuItem: React.StatelessComponent = ({ + userAddress, + onClick, +}) => { + return ( + + + + ); +}; + +export interface LinkSimpleMenuItemProps { + onClick?: () => void; +} +export const GoToAccountManagementSimpleMenuItem: React.StatelessComponent = ({ onClick }) => { + return ( + + + + ); +}; + +export interface DifferentWalletSimpleMenuItemProps { + onClick?: () => void; +} +export const DifferentWalletSimpleMenuItem: React.StatelessComponent = ({ + onClick, +}) => { + return ; }; diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index ab234ae1b..b6ae79b74 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -16,7 +16,12 @@ import { DropDown } from 'ts/components/ui/drop_down'; import { IconButton } from 'ts/components/ui/icon_button'; import { Identicon } from 'ts/components/ui/identicon'; import { Island } from 'ts/components/ui/island'; -import { SimpleMenu, SimpleMenuItem } from 'ts/components/ui/simple_menu'; +import { + CopyAddressSimpleMenuItem, + DifferentWalletSimpleMenuItem, + GoToAccountManagementSimpleMenuItem, + SimpleMenu, +} from 'ts/components/ui/simple_menu'; import { Text } from 'ts/components/ui/text'; import { TokenIcon } from 'ts/components/ui/token_icon'; import { BodyOverlay } from 'ts/components/wallet/body_overlay'; @@ -37,7 +42,6 @@ import { TokenByAddress, TokenState, TokenStateByAddress, - WebsitePaths, } from 'ts/types'; import { analytics } from 'ts/utils/analytics'; import { constants } from 'ts/utils/constants'; @@ -88,7 +92,6 @@ const HEADER_ITEM_KEY = 'HEADER'; const ETHER_ITEM_KEY = 'ETHER'; const USD_DECIMAL_PLACES = 2; const NO_ALLOWANCE_TOGGLE_SPACE_WIDTH = 56; -const ACCOUNT_PATH = `${WebsitePaths.Portal}/account`; const PLACEHOLDER_COLOR = colors.grey300; const LOADING_ROWS_COUNT = 6; @@ -223,16 +226,9 @@ export class Wallet extends React.Component { } popoverContent={ - - - - - - - + + + } anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} -- cgit v1.2.3 From 2dea179333dd14ad74aea65bb6558aac3bb716f4 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sun, 1 Jul 2018 14:44:14 -0700 Subject: More cleanup --- packages/website/ts/components/ui/drop_down.tsx | 1 - packages/website/ts/components/wallet/wallet.tsx | 61 ++++++++++++------------ 2 files changed, 31 insertions(+), 31 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index 3f1fec3f4..947e51be0 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -83,7 +83,6 @@ export class DropDown extends React.Component { ); } private _onActiveNodeClick(event: React.FormEvent): void { - event.stopPropagation(); if (this.props.shouldWaitForClickToActivate) { this.setState({ isDropDownOpen: true, diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index b6ae79b74..56776d255 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -21,6 +21,7 @@ import { DifferentWalletSimpleMenuItem, GoToAccountManagementSimpleMenuItem, SimpleMenu, + SimpleMenuItem, } from 'ts/components/ui/simple_menu'; import { Text } from 'ts/components/ui/text'; import { TokenIcon } from 'ts/components/ui/token_icon'; @@ -207,36 +208,36 @@ export class Wallet extends React.Component { ); const onClick = _.noop; const accessory = ( - - - - - } - popoverContent={ - - - - - - } - anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} - targetOrigin={{ horizontal: 'right', vertical: 'top' }} - zDepth={1} - shouldWaitForClickToActivate={true} - /> - + + + + } + popoverContent={ + + + + + + + + } + anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} + targetOrigin={{ horizontal: 'right', vertical: 'top' }} + zDepth={1} + shouldWaitForClickToActivate={true} + /> ); return ( Date: Sun, 1 Jul 2018 14:48:01 -0700 Subject: Lint fixes --- packages/website/ts/components/top_bar/provider_display.tsx | 13 +++---------- packages/website/ts/components/ui/drop_down.tsx | 2 +- packages/website/ts/components/ui/simple_menu.tsx | 5 +---- packages/website/ts/components/wallet/wallet.tsx | 2 -- 4 files changed, 5 insertions(+), 17 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index c2915f9a9..74f9beedb 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -1,7 +1,6 @@ import { Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import CircularProgress from 'material-ui/CircularProgress'; -import RaisedButton from 'material-ui/RaisedButton'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; import Lock from 'material-ui/svg-icons/action/lock'; import * as React from 'react'; @@ -22,8 +21,7 @@ import { import { Text } from 'ts/components/ui/text'; import { Dispatcher } from 'ts/redux/dispatcher'; import { colors } from 'ts/style/colors'; -import { AccountState, ProviderType, WebsitePaths } from 'ts/types'; -import { constants } from 'ts/utils/constants'; +import { AccountState, ProviderType } from 'ts/types'; import { utils } from 'ts/utils/utils'; const ROOT_HEIGHT = 24; @@ -50,10 +48,6 @@ const styles: Styles = { export class ProviderDisplay extends React.Component { public render(): React.ReactNode { - const isExternallyInjectedProvider = utils.isExternallyInjected( - this.props.providerType, - this.props.injectedProviderName, - ); const activeNode = ( {this._renderIcon()} @@ -63,12 +57,11 @@ export class ProviderDisplay extends React.Component ); - const hasLedgerProvider = this.props.providerType === ProviderType.Ledger; return (
); } - public renderPopoverContent(hasInjectedProvider: boolean, hasLedgerProvider: boolean): React.ReactNode { + private _renderPopoverContent(): React.ReactNode { const accountState = this._getAccountState(); switch (accountState) { case AccountState.Ready: diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index 947e51be0..c21c69993 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -1,4 +1,4 @@ -import Popover, { PopoverAnimationVertical } from 'material-ui/Popover'; +import Popover from 'material-ui/Popover'; import * as React from 'react'; import { MaterialUIPosition } from 'ts/types'; diff --git a/packages/website/ts/components/ui/simple_menu.tsx b/packages/website/ts/components/ui/simple_menu.tsx index 52d97b1ea..c1cab07bd 100644 --- a/packages/website/ts/components/ui/simple_menu.tsx +++ b/packages/website/ts/components/ui/simple_menu.tsx @@ -65,10 +65,7 @@ export const CopyAddressSimpleMenuItem: React.StatelessComponent void; -} -export const GoToAccountManagementSimpleMenuItem: React.StatelessComponent = ({ onClick }) => { +export const GoToAccountManagementSimpleMenuItem: React.StatelessComponent<{}> = () => { return ( diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 56776d255..875e6e78d 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -5,8 +5,6 @@ import * as _ from 'lodash'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; import * as React from 'react'; -import * as CopyToClipboard from 'react-copy-to-clipboard'; -import { Link } from 'react-router-dom'; import firstBy = require('thenby'); import { Blockchain } from 'ts/blockchain'; -- cgit v1.2.3 From b9165c03af40983d885af2b18e729f11746de91d Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 2 Jul 2018 11:07:51 +1000 Subject: Use PrivateKeySubprovider inside eth lightwallet There's a loss of information when hex encoding and passing to eth light wallet (chain id is lost). This results in a different signature. While it may work on testnets it is not sufficient for our test cases. We can export the private key and use it in our PrivateKeyWalletSubprovider --- .../subproviders/eth_lightwallet_subprovider.ts | 40 +++++------- .../test/unit/eth_lightwallet_subprovider_test.ts | 74 ++++++++-------------- .../unit/private_key_wallet_subprovider_test.ts | 14 ++++ 3 files changed, 57 insertions(+), 71 deletions(-) (limited to 'packages') diff --git a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts index 64d984996..b594ffb24 100644 --- a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts +++ b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts @@ -2,11 +2,13 @@ import { assert } from '@0xproject/assert'; import { addressUtils } from '@0xproject/utils'; import * as lightwallet from 'eth-lightwallet'; import EthereumTx = require('ethereumjs-tx'); +import * as ethUtil from 'ethereumjs-util'; import * as _ from 'lodash'; import { PartialTxParams, WalletSubproviderErrors } from '../types'; import { BaseWalletSubprovider } from './base_wallet_subprovider'; +import { PrivateKeyWalletSubprovider } from './private_key_wallet'; /* * This class implements the web3-provider-engine subprovider interface and forwards @@ -42,17 +44,14 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { * @return Signed transaction hex string */ public async signTransactionAsync(txParams: PartialTxParams): Promise { - if (_.isUndefined(txParams.from) || !addressUtils.isAddress(txParams.from)) { - throw new Error(WalletSubproviderErrors.FromAddressMissingOrInvalid); - } - - const tx = new EthereumTx(txParams); - const txHex = tx.serialize().toString('hex'); - let signedTxHex: string = lightwallet.signing.signTx(this._keystore, this._pwDerivedKey, txHex, txParams.from); - - signedTxHex = `0x${signedTxHex}`; - - return signedTxHex; + // Lightwallet loses the chain id information when hex encoding the transaction + // this results in a different signature on certain networks. PrivateKeyWallet + // respects this as it uses the parameters passed in + let privKey = this._keystore.exportPrivateKey(txParams.from, this._pwDerivedKey); + const privKeyWallet = new PrivateKeyWalletSubprovider(privKey); + const privKeySignature = await privKeyWallet.signTransactionAsync(txParams); + privKey = ''; + return privKeySignature; } /** * Sign a personal Ethereum signed message. The signing account will be the account @@ -65,19 +64,10 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { * @return Signature hex string (order: rsv) */ public async signPersonalMessageAsync(data: string, address: string): Promise { - if (_.isUndefined(data)) { - throw new Error(WalletSubproviderErrors.DataMissingForSignPersonalMessage); - } - assert.isHexString('data', data); - assert.isETHAddressHex('address', address); - const result: ECSignatureBuffer = lightwallet.signing.signMsgHash( - this._keystore, - this._pwDerivedKey, - data, - address, - ); - - const signature = lightwallet.signing.concatSig(result); - return signature; + let privKey = this._keystore.exportPrivateKey(address, this._pwDerivedKey); + const privKeyWallet = new PrivateKeyWalletSubprovider(privKey); + privKey = ''; + const result = privKeyWallet.signPersonalMessageAsync(data, address); + return result; } } diff --git a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts index c0adb9225..f17c21f02 100644 --- a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts +++ b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts @@ -1,34 +1,32 @@ import * as chai from 'chai'; import * as lightwallet from 'eth-lightwallet'; import { JSONRPCResponsePayload } from 'ethereum-types'; +import * as ethUtils from 'ethereumjs-util'; import Web3ProviderEngine = require('web3-provider-engine'); import { EthLightwalletSubprovider } from '../../src'; import { DoneCallback } from '../../src/types'; import { chaiSetup } from '../chai_setup'; +import { fixtureData } from '../utils/fixture_data'; import { ganacheSubprovider } from '../utils/ganache_subprovider'; import { reportCallbackErrors } from '../utils/report_callback_errors'; chaiSetup.configure(); const expect = chai.expect; -const FAKE_ADDRESS = '0x44be42fd88e22387c43ba9b75941aa3e680dae25'; -const NUM_GENERATED_ADDRESSES = 10; +const DEFAULT_NUM_ACCOUNTS = 10; const PASSWORD = 'supersecretpassword99'; -const SEED_PHRASE = 'dilemma hollow outer pony cube season start stereo surprise when edit blast'; const SALT = 'kvODghzs7Ff1uqHyI0P3wI4Hso4w4iWT2e9qmrWz0y4'; -const HD_PATH_STRING = `m/44'/60'/0'`; describe('EthLightwalletSubprovider', () => { let ethLightwalletSubprovider: EthLightwalletSubprovider; before(async () => { const options = { password: PASSWORD, - seedPhrase: SEED_PHRASE, + seedPhrase: fixtureData.TEST_RPC_MNEMONIC, salt: SALT, - hdPathString: HD_PATH_STRING, + hdPathString: fixtureData.TESTRPC_BASE_DERIVATION_PATH, }; - const createVaultAsync = async (vaultOptions: lightwallet.VaultOptions) => { return new Promise(resolve => { lightwallet.keystore.createVault(vaultOptions, (err: Error, vaultKeystore) => { @@ -53,7 +51,7 @@ describe('EthLightwalletSubprovider', () => { const pwDerivedKey: Uint8Array = await deriveKeyFromPasswordAsync(keystore); // Generate 10 addresses - keystore.generateNewAddress(pwDerivedKey, NUM_GENERATED_ADDRESSES); + keystore.generateNewAddress(pwDerivedKey, DEFAULT_NUM_ACCOUNTS); ethLightwalletSubprovider = new EthLightwalletSubprovider(keystore, pwDerivedKey); }); @@ -61,22 +59,20 @@ describe('EthLightwalletSubprovider', () => { describe('success cases', () => { it('returns a list of accounts', async () => { const accounts = await ethLightwalletSubprovider.getAccountsAsync(); - expect(accounts[0]).to.be.equal(FAKE_ADDRESS); - expect(accounts.length).to.be.equal(NUM_GENERATED_ADDRESSES); + expect(accounts[0]).to.be.equal(fixtureData.TEST_RPC_ACCOUNT_0); + expect(accounts[1]).to.be.equal(fixtureData.TEST_RPC_ACCOUNT_1); + expect(accounts.length).to.be.equal(DEFAULT_NUM_ACCOUNTS); }); it('signs a personal message hash', async () => { - const signingAccount = (await ethLightwalletSubprovider.getAccountsAsync())[0]; - - // Keccak-256 hash of 'hello world' - const messageHash = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'; - const ecSignatureHex = await ethLightwalletSubprovider.signPersonalMessageAsync( - messageHash, - signingAccount, - ); - expect(ecSignatureHex).to.be.equal( - // tslint:disable-next-line:max-line-length - '0xa46b696c1aa8f91dbb33d1a66f6440bf3cf334c9dc45dc389668c1e60e2db31e259400b41f31632fa994837054c5345c88dc455c13931332489029adee6fd24d1b', - ); + const accounts = await ethLightwalletSubprovider.getAccountsAsync(); + const signingAccount = accounts[0]; + const data = ethUtils.bufferToHex(ethUtils.toBuffer(fixtureData.PERSONAL_MESSAGE_STRING)); + const ecSignatureHex = await ethLightwalletSubprovider.signPersonalMessageAsync(data, signingAccount); + expect(ecSignatureHex).to.be.equal(fixtureData.PERSONAL_MESSAGE_SIGNED_RESULT); + }); + it('signs a transaction', async () => { + const txHex = await ethLightwalletSubprovider.signTransactionAsync(fixtureData.TX_DATA); + expect(txHex).to.be.equal(fixtureData.TX_DATA_SIGNED_RESULT); }); }); }); @@ -98,52 +94,38 @@ describe('EthLightwalletSubprovider', () => { }; const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { expect(err).to.be.a('null'); - expect(response.result.length).to.be.equal(NUM_GENERATED_ADDRESSES); - expect(response.result[0]).to.be.equal(FAKE_ADDRESS); + expect(response.result[0]).to.be.equal(fixtureData.TEST_RPC_ACCOUNT_0); + expect(response.result.length).to.be.equal(DEFAULT_NUM_ACCOUNTS); done(); }); provider.sendAsync(payload, callback); }); it('signs a personal message hash with eth_sign', (done: DoneCallback) => { - // Keccak-256 hash of 'hello world' - const messageHash = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'; + const data = ethUtils.bufferToHex(ethUtils.toBuffer(fixtureData.PERSONAL_MESSAGE_STRING)); + const account = fixtureData.TEST_RPC_ACCOUNT_0; const payload = { jsonrpc: '2.0', method: 'eth_sign', - params: ['0x44be42fd88e22387c43ba9b75941aa3e680dae25', messageHash], + params: [account, data], id: 1, }; const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { expect(err).to.be.a('null'); - expect(response.result).to.be.equal( - // tslint:disable-next-line:max-line-length - '0xa46b696c1aa8f91dbb33d1a66f6440bf3cf334c9dc45dc389668c1e60e2db31e259400b41f31632fa994837054c5345c88dc455c13931332489029adee6fd24d1b', - ); + expect(response.result).to.be.equal(fixtureData.PERSONAL_MESSAGE_SIGNED_RESULT); done(); }); provider.sendAsync(payload, callback); }); it('signs a transaction', (done: DoneCallback) => { - const tx = { - to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66', - value: '0x00', - gasPrice: '0x00', - nonce: '0x00', - gas: '0x00', - from: '0x44be42fd88e22387c43ba9b75941aa3e680dae25', - }; const payload = { jsonrpc: '2.0', method: 'eth_signTransaction', - params: [tx], + params: [fixtureData.TX_DATA], id: 1, }; const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { - const expectedResponseLength = 192; - expect(err).to.be.a('null'); - expect(response.result.raw.length).to.be.equal(expectedResponseLength); - expect(response.result.raw.substr(0, 2)).to.be.equal('0x'); + expect(response.result.raw).to.be.equal(fixtureData.TX_DATA_SIGNED_RESULT); done(); }); provider.sendAsync(payload, callback); @@ -155,7 +137,7 @@ describe('EthLightwalletSubprovider', () => { const payload = { jsonrpc: '2.0', method: 'eth_sign', - params: ['0x0000000000000000000000000000000000000000', nonHexMessage], + params: [fixtureData.TEST_RPC_ACCOUNT_0, nonHexMessage], id: 1, }; const callback = reportCallbackErrors(done)((err: Error, _response: JSONRPCResponsePayload) => { @@ -170,7 +152,7 @@ describe('EthLightwalletSubprovider', () => { const payload = { jsonrpc: '2.0', method: 'personal_sign', - params: [nonHexMessage, '0x0000000000000000000000000000000000000000'], + params: [nonHexMessage, fixtureData.TEST_RPC_ACCOUNT_0], id: 1, }; const callback = reportCallbackErrors(done)((err: Error, _response: JSONRPCResponsePayload) => { diff --git a/packages/subproviders/test/unit/private_key_wallet_subprovider_test.ts b/packages/subproviders/test/unit/private_key_wallet_subprovider_test.ts index a41ad7790..ab321bcff 100644 --- a/packages/subproviders/test/unit/private_key_wallet_subprovider_test.ts +++ b/packages/subproviders/test/unit/private_key_wallet_subprovider_test.ts @@ -60,6 +60,20 @@ describe('PrivateKeyWalletSubprovider', () => { }); provider.sendAsync(payload, callback); }); + it('signs a transaction', (done: DoneCallback) => { + const payload = { + jsonrpc: '2.0', + method: 'eth_signTransaction', + params: [fixtureData.TX_DATA], + id: 1, + }; + const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { + expect(err).to.be.a('null'); + expect(response.result.raw).to.be.equal(fixtureData.TX_DATA_SIGNED_RESULT); + done(); + }); + provider.sendAsync(payload, callback); + }); it('signs a personal message with eth_sign', (done: DoneCallback) => { const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer(fixtureData.PERSONAL_MESSAGE_STRING)); const payload = { -- cgit v1.2.3 From 687802394a6959ca5058ae1a4445d513d04062c6 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 2 Jul 2018 18:09:05 +1000 Subject: Remove duplicate type definitions. Clear private key earlier Fix changelog in typescript-typings from bad merge --- packages/subproviders/src/globals.d.ts | 58 ---------------------- .../subproviders/eth_lightwallet_subprovider.ts | 2 +- packages/typescript-typings/CHANGELOG.json | 1 + 3 files changed, 2 insertions(+), 59 deletions(-) (limited to 'packages') diff --git a/packages/subproviders/src/globals.d.ts b/packages/subproviders/src/globals.d.ts index 287d5e0fe..94e63a32d 100644 --- a/packages/subproviders/src/globals.d.ts +++ b/packages/subproviders/src/globals.d.ts @@ -1,61 +1,3 @@ -// tslint:disable:max-classes-per-file -// tslint:disable:class-name -// tslint:disable:async-suffix -// tslint:disable:completed-docs - -// Ethereumjs-tx declarations - -// Ledgerco declarations -interface ECSignatureString { - v: string; - r: string; - s: string; -} -interface ECSignature { - v: number; - r: string; - s: string; -} -interface ECSignatureBuffer { - v: number; - r: Buffer; - s: Buffer; -} - -interface LedgerTransport { - close(): Promise; -} - -declare module '@ledgerhq/hw-app-eth' { - class Eth { - public transport: LedgerTransport; - constructor(transport: LedgerTransport); - public getAddress( - path: string, - boolDisplay?: boolean, - boolChaincode?: boolean, - ): Promise<{ publicKey: string; address: string; chainCode: string }>; - public signTransaction(path: string, rawTxHex: string): Promise; - public getAppConfiguration(): Promise<{ arbitraryDataEnabled: number; version: string }>; - public signPersonalMessage(path: string, messageHex: string): Promise; - } - export default Eth; -} - -declare module '@ledgerhq/hw-transport-u2f' { - export default class TransportU2F implements LedgerTransport { - public static create(): Promise; - public close(): Promise; - } -} - -declare module '@ledgerhq/hw-transport-node-hid' { - export default class TransportNodeHid implements LedgerTransport { - public static create(): Promise; - public close(): Promise; - } -} - declare module '*.json' { const json: any; /* tslint:disable */ diff --git a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts index b594ffb24..3cd94dac3 100644 --- a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts +++ b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts @@ -49,8 +49,8 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { // respects this as it uses the parameters passed in let privKey = this._keystore.exportPrivateKey(txParams.from, this._pwDerivedKey); const privKeyWallet = new PrivateKeyWalletSubprovider(privKey); - const privKeySignature = await privKeyWallet.signTransactionAsync(txParams); privKey = ''; + const privKeySignature = await privKeyWallet.signTransactionAsync(txParams); return privKeySignature; } /** diff --git a/packages/typescript-typings/CHANGELOG.json b/packages/typescript-typings/CHANGELOG.json index 2e4b8dfdf..1d4230783 100644 --- a/packages/typescript-typings/CHANGELOG.json +++ b/packages/typescript-typings/CHANGELOG.json @@ -6,6 +6,7 @@ "note": "Add types for `eth-lightwallet`", "pr": 775 }, + { "note": "Improve 'web3-provider-engine' typings", "pr": 768 }, -- cgit v1.2.3 From d6f40a9281ef3db8f6daffc17712008a2509a7f0 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 2 Jul 2018 18:14:19 +1000 Subject: Remove duplicated typescript-typings in package.json --- packages/subproviders/package.json | 1 - 1 file changed, 1 deletion(-) (limited to 'packages') diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index 5fd7c3c2d..e5c87ee45 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -42,7 +42,6 @@ "dependencies": { "@0xproject/assert": "^0.2.12", "@0xproject/types": "^1.0.0", - "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", "@ledgerhq/hw-app-eth": "^4.3.0", "@ledgerhq/hw-transport-u2f": "^4.3.0", -- cgit v1.2.3 From d861caca23cd87d162c0d4be62c04d9842c6b84f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 12:31:02 +0200 Subject: Fix bug where 18 decimal tokens instead of 5 decimal tokens created --- packages/contracts/test/utils/core_combinatorial_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/contracts/test/utils/core_combinatorial_utils.ts b/packages/contracts/test/utils/core_combinatorial_utils.ts index 03b09521d..38723d53d 100644 --- a/packages/contracts/test/utils/core_combinatorial_utils.ts +++ b/packages/contracts/test/utils/core_combinatorial_utils.ts @@ -75,7 +75,7 @@ export async function coreCombinatorialUtilsFactoryAsync( const zrxAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address); const erc20FiveDecimalTokenCount = 2; - const fiveDecimals = new BigNumber(18); + const fiveDecimals = new BigNumber(5); const [erc20FiveDecimalTokenA, erc20FiveDecimalTokenB] = await erc20Wrapper.deployDummyTokensAsync( erc20FiveDecimalTokenCount, fiveDecimals, -- cgit v1.2.3 From 9c7289d7a3824e32cb0e88a27e3fa8585da8e1ec Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 13:31:34 +0200 Subject: Update outdated changelogs --- packages/fill-scenarios/CHANGELOG.json | 2 +- packages/json-schemas/CHANGELOG.json | 9 +++++++++ packages/order-utils/CHANGELOG.json | 6 +++++- packages/types/CHANGELOG.json | 8 ++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/fill-scenarios/CHANGELOG.json b/packages/fill-scenarios/CHANGELOG.json index ec9111ebb..822f8d5d5 100644 --- a/packages/fill-scenarios/CHANGELOG.json +++ b/packages/fill-scenarios/CHANGELOG.json @@ -1,6 +1,6 @@ [ { - "version": "0.1.0", + "version": "1.0.0", "changes": [ { "note": "Make fill-scenarios compatible with V2 of 0x protocol", diff --git a/packages/json-schemas/CHANGELOG.json b/packages/json-schemas/CHANGELOG.json index bb9cd3cd2..2b37e1836 100644 --- a/packages/json-schemas/CHANGELOG.json +++ b/packages/json-schemas/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "1.0.0", + "changes": [ + { + "note": "Update schemas for V2", + "pr": 615 + } + ] + }, { "timestamp": 1529397769, "version": "0.8.1", diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index a1f199793..199ce2173 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -1,7 +1,11 @@ [ { - "version": "0.1.0", + "version": "1.0.0", "changes": [ + { + "note": "Refactor to work with V2 of 0x protocol", + "pr": 636 + }, { "note": "Export parseECSignature method", "pr": 684 diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index 40197ab92..a0be5d7fe 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -1,4 +1,12 @@ [ + { + "version": "1.0.0", + "changes": [ + { + "notes": "Updated types for V2 of 0x protocol" + } + ] + }, { "timestamp": 1529397769, "version": "0.8.1", -- cgit v1.2.3 From bdda1f2992ac41ea62ad4bfe2d48988a8e98bf42 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 13:32:22 +0200 Subject: Throw if changelog version is below package.json version --- packages/monorepo-scripts/src/utils/utils.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'packages') diff --git a/packages/monorepo-scripts/src/utils/utils.ts b/packages/monorepo-scripts/src/utils/utils.ts index 20bc57bae..b5d139de3 100644 --- a/packages/monorepo-scripts/src/utils/utils.ts +++ b/packages/monorepo-scripts/src/utils/utils.ts @@ -44,6 +44,9 @@ export const utils = { nextVersionIfValid = semver.inc(currentVersion, 'patch'); } const lastEntry = changelog[0]; + if (semver.gt(currentVersion, lastEntry.version)) { + throw new Error(`Package.json version cannot be greater then last CHANGELOG entry. Check: ${packageName}`); + } nextVersionIfValid = semver.eq(lastEntry.version, currentVersion) ? semver.inc(currentVersion, 'patch') : lastEntry.version; -- cgit v1.2.3 From e4eac14dc977fb5c63661077b51770268abff48b Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 13:53:05 +0200 Subject: version outdated --- packages/ethereum-types/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/ethereum-types/package.json b/packages/ethereum-types/package.json index a937f6ad1..9d4930826 100644 --- a/packages/ethereum-types/package.json +++ b/packages/ethereum-types/package.json @@ -1,6 +1,6 @@ { "name": "ethereum-types", - "version": "0.0.1", + "version": "0.0.2", "engines": { "node": ">=6.12" }, -- cgit v1.2.3 From b763cdbd4cadf151666eda4567be1d8a662877d5 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 13:53:24 +0200 Subject: combine changelog entries since we haven't published yet --- packages/utils/CHANGELOG.json | 13 ++++--------- packages/utils/package.json | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'packages') diff --git a/packages/utils/CHANGELOG.json b/packages/utils/CHANGELOG.json index c6736dc4d..a27216be7 100644 --- a/packages/utils/CHANGELOG.json +++ b/packages/utils/CHANGELOG.json @@ -1,13 +1,4 @@ [ - { - "version": "0.7.3", - "changes": [ - { - "note": "Fixes uncaught Error in abi_decoder", - "pr": 763 - } - ] - }, { "version": "0.7.2", "changes": [ @@ -17,6 +8,10 @@ { "note": "Add logUtils.warn", "pr": 589 + }, + { + "note": "Fixes uncaught Error in abi_decoder", + "pr": 763 } ] }, diff --git a/packages/utils/package.json b/packages/utils/package.json index f4f39956c..442c73109 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/utils", - "version": "0.7.3", + "version": "0.7.2", "engines": { "node": ">=6.12" }, -- cgit v1.2.3 From 1346fa792a381cb4268b79a2167b560d44397db1 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 13:53:44 +0200 Subject: Add logs for when tags get removed --- packages/monorepo-scripts/src/utils/utils.ts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'packages') diff --git a/packages/monorepo-scripts/src/utils/utils.ts b/packages/monorepo-scripts/src/utils/utils.ts index b5d139de3..7019f9241 100644 --- a/packages/monorepo-scripts/src/utils/utils.ts +++ b/packages/monorepo-scripts/src/utils/utils.ts @@ -109,6 +109,7 @@ export const utils = { if (!_.isEmpty(result.stderr)) { throw new Error(`Failed to delete local git tag. Got err: ${result.stderr}`); } + this.log(`Removed local tag: ${tagName}`); }, async removeRemoteTagAsync(tagName: string): Promise { const result = await execAsync(`git push origin ${tagName}`, { @@ -117,5 +118,6 @@ export const utils = { if (!_.isEmpty(result.stderr)) { throw new Error(`Failed to delete remote git tag. Got err: ${result.stderr}`); } + this.log(`Removed remote tag: ${tagName}`); }, }; -- cgit v1.2.3 From a619949a56937d29b3e7463812e9ea8515d21126 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 14:19:30 +0200 Subject: Remove remote tag before local one --- packages/monorepo-scripts/src/prepublish_checks.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'packages') diff --git a/packages/monorepo-scripts/src/prepublish_checks.ts b/packages/monorepo-scripts/src/prepublish_checks.ts index 1c4ee1fc6..3b4ff9082 100644 --- a/packages/monorepo-scripts/src/prepublish_checks.ts +++ b/packages/monorepo-scripts/src/prepublish_checks.ts @@ -34,17 +34,17 @@ async function checkGitTagsForNextVersionAndDeleteIfExistAsync( const packageLocation = lernaPackage.location; const nextVersion = await utils.getNextPackageVersionAsync(currentVersion, packageName, packageLocation); - const localTagVersions = localTagVersionsByPackageName[packageName]; - if (_.includes(localTagVersions, nextVersion)) { - const tagName = `${packageName}@${nextVersion}`; - await utils.removeLocalTagAsync(tagName); - } - const remoteTagVersions = remoteTagVersionsByPackageName[packageName]; if (_.includes(remoteTagVersions, nextVersion)) { const tagName = `:refs/tags/${packageName}@${nextVersion}`; await utils.removeRemoteTagAsync(tagName); } + + const localTagVersions = localTagVersionsByPackageName[packageName]; + if (_.includes(localTagVersions, nextVersion)) { + const tagName = `${packageName}@${nextVersion}`; + await utils.removeLocalTagAsync(tagName); + } } } -- cgit v1.2.3 From e553ef83de473fd493f32158bc61e39778acc623 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 14:20:42 +0200 Subject: Git command outputs logs to stdErr so only way to check for errors if with try/catch --- packages/monorepo-scripts/src/utils/utils.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'packages') diff --git a/packages/monorepo-scripts/src/utils/utils.ts b/packages/monorepo-scripts/src/utils/utils.ts index 7019f9241..4d3e2d709 100644 --- a/packages/monorepo-scripts/src/utils/utils.ts +++ b/packages/monorepo-scripts/src/utils/utils.ts @@ -103,20 +103,22 @@ export const utils = { return tagVersionByPackageName; }, async removeLocalTagAsync(tagName: string): Promise { - const result = await execAsync(`git tag -d ${tagName}`, { + try { + await execAsync(`git tag -d ${tagName}`, { cwd: constants.monorepoRootPath, }); - if (!_.isEmpty(result.stderr)) { - throw new Error(`Failed to delete local git tag. Got err: ${result.stderr}`); + } catch (err) { + throw new Error(`Failed to delete local git tag. Got err: ${err}`); } this.log(`Removed local tag: ${tagName}`); }, async removeRemoteTagAsync(tagName: string): Promise { - const result = await execAsync(`git push origin ${tagName}`, { + try { + await execAsync(`git push origin ${tagName}`, { cwd: constants.monorepoRootPath, }); - if (!_.isEmpty(result.stderr)) { - throw new Error(`Failed to delete remote git tag. Got err: ${result.stderr}`); + } catch (err) { + throw new Error(`Failed to delete remote git tag. Got err: ${err}`); } this.log(`Removed remote tag: ${tagName}`); }, -- cgit v1.2.3 From db0944acde0f787f075ede55bf278108d20caf25 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 14:21:49 +0200 Subject: fix prettier --- packages/monorepo-scripts/src/utils/utils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'packages') diff --git a/packages/monorepo-scripts/src/utils/utils.ts b/packages/monorepo-scripts/src/utils/utils.ts index 4d3e2d709..f819ab6f1 100644 --- a/packages/monorepo-scripts/src/utils/utils.ts +++ b/packages/monorepo-scripts/src/utils/utils.ts @@ -105,8 +105,8 @@ export const utils = { async removeLocalTagAsync(tagName: string): Promise { try { await execAsync(`git tag -d ${tagName}`, { - cwd: constants.monorepoRootPath, - }); + cwd: constants.monorepoRootPath, + }); } catch (err) { throw new Error(`Failed to delete local git tag. Got err: ${err}`); } @@ -115,8 +115,8 @@ export const utils = { async removeRemoteTagAsync(tagName: string): Promise { try { await execAsync(`git push origin ${tagName}`, { - cwd: constants.monorepoRootPath, - }); + cwd: constants.monorepoRootPath, + }); } catch (err) { throw new Error(`Failed to delete remote git tag. Got err: ${err}`); } -- cgit v1.2.3 From 6aad12a52fa4db31a588cefc088d784949c65b06 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 14:26:52 +0200 Subject: Add new changelog entry --- packages/monorepo-scripts/CHANGELOG.json | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'packages') diff --git a/packages/monorepo-scripts/CHANGELOG.json b/packages/monorepo-scripts/CHANGELOG.json index a1dda0176..781704a8e 100644 --- a/packages/monorepo-scripts/CHANGELOG.json +++ b/packages/monorepo-scripts/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "0.2.2", + "changes": [ + { + "note": "Fix git remote tag removal step & add an additional sanity assertion", + "pr": 803 + } + ] + }, { "timestamp": 1529397769, "version": "0.2.1", -- cgit v1.2.3 From 50957e1d29674e8cb5e451ec576899ba8c15dde2 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Jul 2018 16:04:48 +0200 Subject: Update incorrect versions of deps --- packages/0x.js/package.json | 2 +- packages/abi-gen/package.json | 2 +- packages/base-contract/package.json | 2 +- packages/contract-wrappers/package.json | 2 +- packages/contracts/package.json | 2 +- packages/dev-utils/package.json | 2 +- packages/fill-scenarios/package.json | 2 +- packages/migrations/package.json | 2 +- packages/order-utils/package.json | 2 +- packages/order-watcher/package.json | 4 ++-- packages/sol-compiler/package.json | 2 +- packages/sol-cov/package.json | 2 +- packages/subproviders/package.json | 2 +- packages/testnet-faucets/package.json | 2 +- packages/types/package.json | 2 +- packages/typescript-typings/package.json | 2 +- packages/utils/package.json | 2 +- packages/web3-wrapper/package.json | 2 +- 18 files changed, 19 insertions(+), 19 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 12fbf0347..1b41a7cf2 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -110,7 +110,7 @@ "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", "@0xproject/web3-wrapper": "^0.7.1", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "ethers": "3.0.22", "lodash": "^4.17.4" }, diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json index 9d3c6d00d..dadf1dbfe 100644 --- a/packages/abi-gen/package.json +++ b/packages/abi-gen/package.json @@ -29,7 +29,7 @@ "dependencies": { "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "chalk": "^2.3.0", "glob": "^7.1.2", "handlebars": "^4.0.11", diff --git a/packages/base-contract/package.json b/packages/base-contract/package.json index ecbde213b..3b9383033 100644 --- a/packages/base-contract/package.json +++ b/packages/base-contract/package.json @@ -43,7 +43,7 @@ "typescript": "2.7.1" }, "dependencies": { - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", "@0xproject/web3-wrapper": "^0.7.1", diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index fe98e08bf..1b4835be6 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -86,7 +86,7 @@ "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", "@0xproject/web3-wrapper": "^0.7.1", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "ethereumjs-blockstream": "^2.0.6", "ethereumjs-util": "^5.1.1", "ethers": "3.0.22", diff --git a/packages/contracts/package.json b/packages/contracts/package.json index e0e82adc7..01f2320d0 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -80,7 +80,7 @@ "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", "@0xproject/web3-wrapper": "^0.7.1", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "bn.js": "^4.11.8", "ethereumjs-abi": "^0.6.4", "ethereumjs-util": "^5.1.1", diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index e62075054..621053ed7 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -48,7 +48,7 @@ "@0xproject/subproviders": "^0.10.4", "@0xproject/types": "^0.8.1", "@0xproject/utils": "^0.7.1", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "@0xproject/typescript-typings": "^0.4.1", "@0xproject/web3-wrapper": "^0.7.1", "lodash": "^4.17.4", diff --git a/packages/fill-scenarios/package.json b/packages/fill-scenarios/package.json index 883300fa0..91024ed34 100644 --- a/packages/fill-scenarios/package.json +++ b/packages/fill-scenarios/package.json @@ -44,7 +44,7 @@ "@0xproject/base-contract": "^0.3.4", "@0xproject/order-utils": "^1.0.0", "@0xproject/types": "1.0.0", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", "@0xproject/web3-wrapper": "^0.7.1", diff --git a/packages/migrations/package.json b/packages/migrations/package.json index 57bf0875a..f4190a771 100644 --- a/packages/migrations/package.json +++ b/packages/migrations/package.json @@ -67,7 +67,7 @@ "@0xproject/utils": "^0.7.1", "@0xproject/web3-wrapper": "^0.7.1", "@ledgerhq/hw-app-eth": "^4.3.0", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "ethers": "3.0.22", "lodash": "^4.17.4", "web3-provider-engine": "^14.0.4" diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json index e3c81de44..97b08c3d3 100644 --- a/packages/order-utils/package.json +++ b/packages/order-utils/package.json @@ -82,7 +82,7 @@ "@0xproject/web3-wrapper": "^0.7.1", "@types/node": "^8.0.53", "bn.js": "^4.11.8", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "ethereumjs-abi": "^0.6.4", "ethereumjs-util": "^5.1.1", "ethers": "3.0.22", diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json index 3335713a3..40613ea96 100644 --- a/packages/order-watcher/package.json +++ b/packages/order-watcher/package.json @@ -85,9 +85,9 @@ "@0xproject/order-utils": "^0.0.7", "@0xproject/types": "^0.8.1", "@0xproject/typescript-typings": "^0.4.1", - "@0xproject/utils": "^0.7.3", + "@0xproject/utils": "^0.7.2", "@0xproject/web3-wrapper": "^0.7.1", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "bintrees": "^1.0.2", "ethers": "3.0.22", "lodash": "^4.17.4" diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json index 98568c270..2c1fa41b3 100644 --- a/packages/sol-compiler/package.json +++ b/packages/sol-compiler/package.json @@ -84,7 +84,7 @@ "@0xproject/utils": "^0.7.1", "@0xproject/web3-wrapper": "^0.7.1", "@types/yargs": "^11.0.0", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "chalk": "^2.3.0", "ethereumjs-util": "^5.1.1", "isomorphic-fetch": "^2.2.1", diff --git a/packages/sol-cov/package.json b/packages/sol-cov/package.json index 3d1b7f900..483500ca9 100644 --- a/packages/sol-cov/package.json +++ b/packages/sol-cov/package.json @@ -56,7 +56,7 @@ "@0xproject/utils": "^0.7.1", "@0xproject/web3-wrapper": "^0.7.1", "@0xproject/dev-utils": "^0.4.4", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "ethereumjs-util": "^5.1.1", "glob": "^7.1.2", "istanbul": "^0.4.5", diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index 31b6ffed6..e87d7bf94 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -46,7 +46,7 @@ "@0xproject/utils": "^0.7.1", "@ledgerhq/hw-app-eth": "^4.3.0", "@ledgerhq/hw-transport-u2f": "^4.3.0", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "bip39": "^2.5.0", "bn.js": "^4.11.8", "ethereumjs-tx": "^1.3.5", diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index 712ac6795..fdd71656a 100644 --- a/packages/testnet-faucets/package.json +++ b/packages/testnet-faucets/package.json @@ -36,7 +36,7 @@ "@types/body-parser": "^1.16.1", "@types/express": "^4.0.35", "@types/lodash": "4.14.104", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "awesome-typescript-loader": "^3.1.3", "gulp": "^3.9.1", "make-promises-safe": "^1.1.0", diff --git a/packages/types/package.json b/packages/types/package.json index 0d5e308b9..f79b558fa 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -35,7 +35,7 @@ "dependencies": { "@types/node": "^8.0.53", "bignumber.js": "~4.1.0", - "ethereum-types": "^0.0.1" + "ethereum-types": "^0.0.2" }, "publishConfig": { "access": "public" diff --git a/packages/typescript-typings/package.json b/packages/typescript-typings/package.json index 3ba7c10ba..e3f226294 100644 --- a/packages/typescript-typings/package.json +++ b/packages/typescript-typings/package.json @@ -25,7 +25,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/typescript-typings#readme", "dependencies": { - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "bignumber.js": "~4.1.0" }, "devDependencies": { diff --git a/packages/utils/package.json b/packages/utils/package.json index 442c73109..f10594de5 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -35,7 +35,7 @@ "typescript": "2.7.1" }, "dependencies": { - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "@0xproject/typescript-typings": "^0.4.2", "@types/node": "^8.0.53", "ethereumjs-util": "^5.1.1", diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json index 5f7f2cb00..05d195bb9 100644 --- a/packages/web3-wrapper/package.json +++ b/packages/web3-wrapper/package.json @@ -66,7 +66,7 @@ "dependencies": { "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", - "ethereum-types": "^0.0.1", + "ethereum-types": "^0.0.2", "ethers": "3.0.22", "lodash": "^4.17.4", "web3": "^0.20.0" -- cgit v1.2.3 From 4887d1d42fe88db88d40a4ed2531277d495147ec Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Sun, 1 Jul 2018 20:22:57 -0400 Subject: in subproviders, cite typescript-typings only once `yarn build` was giving the following warning: warning package.json: "dependencies" has dependency "@0xproject/typescript-typings" with range "^0.4.1" that collides with a dependency in "devDependencies" of the same name with version "^0.4.2" --- packages/subproviders/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index 31b6ffed6..013abb155 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -42,7 +42,7 @@ "dependencies": { "@0xproject/assert": "^0.2.12", "@0xproject/types": "^0.8.1", - "@0xproject/typescript-typings": "^0.4.1", + "@0xproject/typescript-typings": "^0.4.2", "@0xproject/utils": "^0.7.1", "@ledgerhq/hw-app-eth": "^4.3.0", "@ledgerhq/hw-transport-u2f": "^4.3.0", @@ -61,7 +61,6 @@ "devDependencies": { "@0xproject/monorepo-scripts": "^0.2.1", "@0xproject/tslint-config": "^0.4.20", - "@0xproject/typescript-typings": "^0.4.2", "@0xproject/utils": "^0.7.1", "@types/bip39": "^2.4.0", "@types/bn.js": "^4.11.0", -- cgit v1.2.3 From 06f4427939123cae8273bb5cc33cd90ac65a2f59 Mon Sep 17 00:00:00 2001 From: fragosti Date: Mon, 2 Jul 2018 13:15:40 -0700 Subject: Add Alex Browne to about page --- packages/website/public/images/team/alexbrowne.png | Bin 0 -> 146699 bytes packages/website/ts/pages/about/about.tsx | 29 ++++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 packages/website/public/images/team/alexbrowne.png (limited to 'packages') diff --git a/packages/website/public/images/team/alexbrowne.png b/packages/website/public/images/team/alexbrowne.png new file mode 100644 index 000000000..76a61913e Binary files /dev/null and b/packages/website/public/images/team/alexbrowne.png differ diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx index 0259af36f..5bb5d06a9 100644 --- a/packages/website/ts/pages/about/about.tsx +++ b/packages/website/ts/pages/about/about.tsx @@ -165,16 +165,24 @@ const teamRow5: ProfileInfo[] = [ }, ]; -// const teamRow6: ProfileInfo[] = [ -// { -// name: 'Chris Kalani', -// title: 'Director of Design', -// description: `Previously founded Wake (acquired by InVision). Early Facebook product designer.`, -// image: 'images/team/chris.png', -// linkedIn: 'https://www.linkedin.com/in/chriskalani/', -// github: 'https://github.com/chriskalani', -// }, -// ]; +const teamRow6: ProfileInfo[] = [ + { + name: 'Alex Browne', + title: 'Engineer in Residence', + description: `Full-stack blockchain engineer. Previously at Plaid. Open source guru and footgun dismantler. Computer Science and Electrical Engineering at Duke.`, + image: 'images/team/alexbrowne.png', + linkedIn: 'https://www.linkedin.com/in/stephenalexbrowne/', + github: 'http://github.com/albrow', + }, + // { + // name: 'Chris Kalani', + // title: 'Director of Design', + // description: `Previously founded Wake (acquired by InVision). Early Facebook product designer.`, + // image: 'images/team/chris.png', + // linkedIn: 'https://www.linkedin.com/in/chriskalani/', + // github: 'https://github.com/chriskalani', + // }, +]; const advisors: ProfileInfo[] = [ { @@ -270,6 +278,7 @@ export class About extends React.Component {
{this._renderProfiles(teamRow3)}
{this._renderProfiles(teamRow4)}
{this._renderProfiles(teamRow5)}
+
{this._renderProfiles(teamRow6)}
Date: Mon, 2 Jul 2018 15:52:59 -0700 Subject: Only auto-start onboarding if blockchain is loaded --- .../website/ts/components/onboarding/portal_onboarding_flow.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 6bfa5c75f..6d8007659 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -46,7 +46,7 @@ class PlainPortalOnboardingFlow extends React.Component this.props.updateIsRunning(false)); } @@ -61,6 +61,9 @@ class PlainPortalOnboardingFlow extends React.Component Date: Mon, 2 Jul 2018 15:58:53 -0700 Subject: Remove max-width from onboarding card to support iPad --- packages/website/ts/components/onboarding/onboarding_card.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/website/ts/components/onboarding/onboarding_card.tsx b/packages/website/ts/components/onboarding/onboarding_card.tsx index 48e8ab022..ba5b3d6ea 100644 --- a/packages/website/ts/components/onboarding/onboarding_card.tsx +++ b/packages/website/ts/components/onboarding/onboarding_card.tsx @@ -39,7 +39,7 @@ export const OnboardingCard: React.StatelessComponent = ({ borderRadius, }) => ( - +
{title} -- cgit v1.2.3 From bc7e8ff471d7abe8e65b30d1945f6a989d521f10 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 2 Jul 2018 16:00:34 -0700 Subject: Add better balance formatting rules for balances and usd values --- packages/website/package.json | 2 ++ packages/website/ts/components/wallet/wallet.tsx | 20 +++++--------------- packages/website/ts/utils/constants.ts | 3 ++- packages/website/ts/utils/utils.ts | 16 ++++++++++++++-- 4 files changed, 23 insertions(+), 18 deletions(-) (limited to 'packages') diff --git a/packages/website/package.json b/packages/website/package.json index c7b689356..cc7b7c05c 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -38,6 +38,7 @@ "lodash": "^4.17.4", "material-ui": "^0.17.1", "moment": "2.21.0", + "numeral": "^2.0.6", "polished": "^1.9.2", "query-string": "^6.0.0", "react": "15.6.1", @@ -71,6 +72,7 @@ "@types/lodash": "4.14.104", "@types/material-ui": "0.18.0", "@types/node": "^8.0.53", + "@types/numeral": "^0.0.22", "@types/query-string": "^5.1.0", "@types/react": "16.3.13", "@types/react-copy-to-clipboard": "^4.2.0", diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 1f1e3598a..668a7a537 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -1,6 +1,5 @@ import { constants as sharedConstants, EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; import { BigNumber, errorUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; @@ -83,7 +82,6 @@ const ICON_DIMENSION = 28; const BODY_ITEM_KEY = 'BODY'; const HEADER_ITEM_KEY = 'HEADER'; const ETHER_ITEM_KEY = 'ETHER'; -const USD_DECIMAL_PLACES = 2; const NO_ALLOWANCE_TOGGLE_SPACE_WIDTH = 56; const ACCOUNT_PATH = `${WebsitePaths.Portal}/account`; const PLACEHOLDER_COLOR = colors.grey300; @@ -411,19 +409,11 @@ export class Wallet extends React.Component { price?: BigNumber, isLoading: boolean = false, ): React.ReactNode { - let result; - if (!isLoading) { - if (_.isUndefined(price)) { - result = '--'; - } else { - const unitAmount = Web3Wrapper.toUnitAmount(amount, decimals); - const value = unitAmount.mul(price); - const formattedAmount = value.toFixed(USD_DECIMAL_PLACES); - result = `$${formattedAmount}`; - } - } else { - result = '$0.00'; - } + const result = !isLoading + ? _.isUndefined(price) + ? '--' + : utils.getUsdValueFormattedAmount(amount, decimals, price) + : '$0.00'; return ( diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts index d3a2aa107..71c0092d2 100644 --- a/packages/website/ts/utils/constants.ts +++ b/packages/website/ts/utils/constants.ts @@ -6,7 +6,7 @@ export const constants = { ETHER_TOKEN_SYMBOL: 'WETH', ZRX_TOKEN_SYMBOL: 'ZRX', ETHER_SYMBOL: 'ETH', - TOKEN_AMOUNT_DISPLAY_PRECISION: 5, + TOKEN_AMOUNT_DISPLAY_PRECISION: 4, GENESIS_ORDER_BLOCK_BY_NETWORK_ID: { 1: 4145578, 42: 3117574, @@ -38,6 +38,7 @@ export const constants = { UNAVAILABLE_STATUS: 503, TAKER_FEE: new BigNumber(0), TESTNET_NAME: 'Kovan', + NUMERAL_USD_FORMAT: '$0,0.00', PROJECT_URL_ETHFINEX: 'https://www.ethfinex.com/', PROJECT_URL_AMADEUS: 'http://amadeusrelay.org', PROJECT_URL_DDEX: 'https://ddex.io', diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts index 726e1815f..b27c6e48b 100644 --- a/packages/website/ts/utils/utils.ts +++ b/packages/website/ts/utils/utils.ts @@ -8,6 +8,8 @@ import * as bowser from 'bowser'; import deepEqual = require('deep-equal'); import * as _ from 'lodash'; import * as moment from 'moment'; +import * as numeral from 'numeral'; + import { AccountState, BlockchainCallErrs, @@ -380,10 +382,20 @@ export const utils = { }, getFormattedAmount(amount: BigNumber, decimals: number, symbol: string): string { const unitAmount = Web3Wrapper.toUnitAmount(amount, decimals); - const precision = Math.min(constants.TOKEN_AMOUNT_DISPLAY_PRECISION, unitAmount.decimalPlaces()); - const formattedAmount = unitAmount.toFixed(precision); + // if the unit amount is less than 1, show the natural number of decimal places with a max of 4 + // if the unit amount is greater than or equal to 1, show only 2 decimal places + const precision = unitAmount.lt(1) + ? Math.min(constants.TOKEN_AMOUNT_DISPLAY_PRECISION, unitAmount.decimalPlaces()) + : 2; + const format = `0,0.${_.repeat('0', precision)}`; + const formattedAmount = numeral(unitAmount).format(format); return `${formattedAmount} ${symbol}`; }, + getUsdValueFormattedAmount(amount: BigNumber, decimals: number, price: BigNumber): string { + const unitAmount = Web3Wrapper.toUnitAmount(amount, decimals); + const value = unitAmount.mul(price); + return numeral(value).format(constants.NUMERAL_USD_FORMAT); + }, openUrl(url: string): void { window.open(url, '_blank'); }, -- cgit v1.2.3 From 2eede4a09ecd17cade6623b4a770a62bee57a2e8 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 2 Jul 2018 16:30:13 -0700 Subject: Update start onboarding copy and relayer grid empty color --- packages/website/public/images/setup_account_icon.svg | 3 +++ packages/website/ts/components/portal/portal.tsx | 12 ++++++------ .../ts/components/relayer_index/relayer_grid_tile.tsx | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 packages/website/public/images/setup_account_icon.svg (limited to 'packages') diff --git a/packages/website/public/images/setup_account_icon.svg b/packages/website/public/images/setup_account_icon.svg new file mode 100644 index 000000000..eaa5b2fd6 --- /dev/null +++ b/packages/website/public/images/setup_account_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx index 9c0cb866d..8c3b5cfd7 100644 --- a/packages/website/ts/components/portal/portal.tsx +++ b/packages/website/ts/components/portal/portal.tsx @@ -1,7 +1,6 @@ import { colors, constants as sharedConstants } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; -import Help from 'material-ui/svg-icons/action/help'; import * as React from 'react'; import * as DocumentTitle from 'react-document-title'; import { Link, Route, RouteComponentProps, Switch } from 'react-router-dom'; @@ -24,6 +23,7 @@ import { TopBar, TopBarDisplayType } from 'ts/components/top_bar/top_bar'; import { TradeHistory } from 'ts/components/trade_history/trade_history'; import { Container } from 'ts/components/ui/container'; import { FlashMessage } from 'ts/components/ui/flash_message'; +import { Image } from 'ts/components/ui/image'; import { Text } from 'ts/components/ui/text'; import { Wallet } from 'ts/components/wallet/wallet'; import { GenerateOrderForm } from 'ts/containers/generate_order_form'; @@ -368,11 +368,11 @@ export class Portal extends React.Component { const shouldStartOnboarding = !isMobile || this.props.location.pathname === `${WebsitePaths.Portal}/account`; const startOnboarding = ( - - - - Learn how to set up your account - + + Set up your account to start trading + + + ); diff --git a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx index b26bf512b..80ff8c7ff 100644 --- a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx +++ b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx @@ -55,7 +55,7 @@ const styles: Styles = { }; const FALLBACK_IMG_SRC = '/images/relayer_fallback.png'; -const FALLBACK_PRIMARY_COLOR = colors.grey200; +const FALLBACK_PRIMARY_COLOR = colors.grey300; const NO_CONTENT_MESSAGE = '--'; const RELAYER_ICON_HEIGHT = '110px'; -- cgit v1.2.3 From 04d11d6fac265d8e43de8c14cab78655bb90d035 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 2 Jul 2018 13:38:02 -0700 Subject: Add human readable names for Toshi and Cipher --- packages/website/ts/blockchain.ts | 2 ++ packages/website/ts/types.ts | 2 ++ packages/website/ts/utils/constants.ts | 2 ++ packages/website/ts/utils/utils.ts | 5 +++++ 4 files changed, 11 insertions(+) (limited to 'packages') diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index d18c34c32..b59306974 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -73,6 +73,8 @@ const providerToName: { [provider: string]: string } = { [Providers.Metamask]: constants.PROVIDER_NAME_METAMASK, [Providers.Parity]: constants.PROVIDER_NAME_PARITY_SIGNER, [Providers.Mist]: constants.PROVIDER_NAME_MIST, + [Providers.Toshi]: constants.PROVIDER_NAME_TOSHI, + [Providers.Cipher]: constants.PROVIDER_NAME_CIPHER, }; export class Blockchain { diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 498a0a5b8..2e4cf84d0 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -487,6 +487,8 @@ export enum Providers { Parity = 'PARITY', Metamask = 'METAMASK', Mist = 'MIST', + Toshi = 'TOSHI', + Cipher = 'CIPHER', } export interface InjectedProviderUpdate { diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts index d3a2aa107..b0cb2fa08 100644 --- a/packages/website/ts/utils/constants.ts +++ b/packages/website/ts/utils/constants.ts @@ -29,6 +29,8 @@ export const constants = { PROVIDER_NAME_METAMASK: 'MetaMask', PROVIDER_NAME_PARITY_SIGNER: 'Parity Signer', PROVIDER_NAME_MIST: 'Mist', + PROVIDER_NAME_CIPHER: 'Cipher Browser', + PROVIDER_NAME_TOSHI: 'Toshi', PROVIDER_NAME_GENERIC: 'Injected Web3', PROVIDER_NAME_PUBLIC: '0x Public', ROLLBAR_ACCESS_TOKEN: 'a6619002b51c4464928201e6ea94de65', diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts index 726e1815f..0ef3d6723 100644 --- a/packages/website/ts/utils/utils.ts +++ b/packages/website/ts/utils/utils.ts @@ -324,6 +324,7 @@ export const utils = { getProviderType(provider: Provider): Providers | string { const constructorName = provider.constructor.name; let parsedProviderName = constructorName; + // https://ethereum.stackexchange.com/questions/24266/elegant-way-to-detect-current-provider-int-web3-js switch (constructorName) { case 'EthereumProvider': parsedProviderName = Providers.Mist; @@ -337,6 +338,10 @@ export const utils = { parsedProviderName = Providers.Parity; } else if ((provider as any).isMetaMask) { parsedProviderName = Providers.Metamask; + } else if (!_.isUndefined(_.get(window, 'SOFA'))) { + parsedProviderName = Providers.Toshi; + } else if (!_.isUndefined(_.get(window, '__CIPHER__'))) { + parsedProviderName = Providers.Cipher; } return parsedProviderName; }, -- cgit v1.2.3 From 73d8a2adf748e06552a1a7a7a188433c4c41095b Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 2 Jul 2018 16:52:20 -0700 Subject: Always show the wrap ether row in between ETH and WETH --- packages/website/ts/components/wallet/wallet.tsx | 33 +++++++++++----------- .../ts/components/wallet/wrap_ether_item.tsx | 5 ++-- 2 files changed, 20 insertions(+), 18 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 1f1e3598a..a75404637 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -320,8 +320,24 @@ export class Wallet extends React.Component { this.state.wrappedEtherDirection === accessoryItemConfig.wrappedEtherDirection && !_.isUndefined(this.props.userEtherBalanceInWei); const etherToken = this._getEthToken(); + const wrapEtherItem = shouldShowWrapEtherItem ? ( + this.props.refetchTokenStateAsync(etherToken.address)} + /> + ) : null; return (
+ {this.state.wrappedEtherDirection === Side.Receive && wrapEtherItem} {
} accessory={this._renderAccessoryItems(accessoryItemConfig)} - backgroundColor={shouldShowWrapEtherItem ? colors.walletFocusedItemBackground : undefined} /> - {shouldShowWrapEtherItem && ( - this.props.refetchTokenStateAsync(etherToken.address)} - /> - )} + {this.state.wrappedEtherDirection === Side.Deposit && wrapEtherItem}
); } diff --git a/packages/website/ts/components/wallet/wrap_ether_item.tsx b/packages/website/ts/components/wallet/wrap_ether_item.tsx index 851b35f90..2b4cf93fe 100644 --- a/packages/website/ts/components/wallet/wrap_ether_item.tsx +++ b/packages/website/ts/components/wallet/wrap_ether_item.tsx @@ -8,6 +8,7 @@ import * as React from 'react'; import { Blockchain } from 'ts/blockchain'; import { EthAmountInput } from 'ts/components/inputs/eth_amount_input'; import { TokenAmountInput } from 'ts/components/inputs/token_amount_input'; +import { Container } from 'ts/components/ui/container'; import { Dispatcher } from 'ts/redux/dispatcher'; import { colors } from 'ts/style/colors'; import { BlockchainCallErrs, Side, Token } from 'ts/types'; @@ -94,7 +95,7 @@ export class WrapEtherItem extends React.Component +
{this._renderIsEthConversionHappeningSpinner()}
{topLabelText}
@@ -142,7 +143,7 @@ export class WrapEtherItem extends React.Component -
+
); } private _onValueChange(_isValid: boolean, amount?: BigNumber): void { -- cgit v1.2.3 From fd545ec00fc0f4b0a64db8cdb3d5c217e45a6b6a Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 2 Jul 2018 17:11:54 -0700 Subject: Remove increase balance link from balance_bounded_input component --- .../dialogs/eth_weth_conversion_dialog.tsx | 2 -- .../website/ts/components/dialogs/send_dialog.tsx | 1 - .../ts/components/inputs/balance_bounded_input.tsx | 35 ++-------------------- .../ts/components/inputs/eth_amount_input.tsx | 4 --- .../ts/components/inputs/token_amount_input.tsx | 2 -- 5 files changed, 2 insertions(+), 42 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx index 9ac78e80e..7b09cc92c 100644 --- a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx +++ b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx @@ -103,7 +103,6 @@ export class EthWethConversionDialog extends React.Component< shouldCheckAllowance={false} onChange={this._onValueChange.bind(this)} amount={this.state.value} - onVisitBalancesPageClick={this.props.onCancelled} /> ) : ( )}
diff --git a/packages/website/ts/components/dialogs/send_dialog.tsx b/packages/website/ts/components/dialogs/send_dialog.tsx index 421f18b4f..8a98fdf69 100644 --- a/packages/website/ts/components/dialogs/send_dialog.tsx +++ b/packages/website/ts/components/dialogs/send_dialog.tsx @@ -80,7 +80,6 @@ export class SendDialog extends React.Component
diff --git a/packages/website/ts/components/inputs/balance_bounded_input.tsx b/packages/website/ts/components/inputs/balance_bounded_input.tsx index 968609030..f23beb436 100644 --- a/packages/website/ts/components/inputs/balance_bounded_input.tsx +++ b/packages/website/ts/components/inputs/balance_bounded_input.tsx @@ -3,9 +3,8 @@ import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import TextField from 'material-ui/TextField'; import * as React from 'react'; -import { Link } from 'react-router-dom'; import { RequiredLabel } from 'ts/components/ui/required_label'; -import { ValidatedBigNumberCallback, WebsitePaths } from 'ts/types'; +import { ValidatedBigNumberCallback } from 'ts/types'; import { utils } from 'ts/utils/utils'; interface BalanceBoundedInputProps { @@ -18,8 +17,6 @@ interface BalanceBoundedInputProps { shouldShowIncompleteErrs?: boolean; shouldCheckBalance: boolean; validate?: (amount: BigNumber) => React.ReactNode; - onVisitBalancesPageClick?: () => void; - shouldHideVisitBalancesLink?: boolean; isDisabled?: boolean; shouldShowErrs?: boolean; shouldShowUnderline?: boolean; @@ -35,7 +32,6 @@ interface BalanceBoundedInputState { export class BalanceBoundedInput extends React.Component { public static defaultProps: Partial = { shouldShowIncompleteErrs: false, - shouldHideVisitBalancesLink: false, isDisabled: false, shouldShowErrs: true, hintText: 'amount', @@ -124,38 +120,11 @@ export class BalanceBoundedInput extends React.ComponentInsufficient balance. {this._renderIncreaseBalanceLink()}; + return Insufficient balance.; } const errMsg = _.isUndefined(this.props.validate) ? undefined : this.props.validate(amount); return errMsg; } - private _renderIncreaseBalanceLink(): React.ReactNode { - if (this.props.shouldHideVisitBalancesLink) { - return null; - } - - const increaseBalanceText = 'Increase balance'; - const linkStyle = { - cursor: 'pointer', - color: colors.darkestGrey, - textDecoration: 'underline', - display: 'inline', - }; - if (_.isUndefined(this.props.onVisitBalancesPageClick)) { - return ( - - {increaseBalanceText} - - ); - } else { - return ( -
- {increaseBalanceText} -
- ); - } - } - private _setAmountState(amount: string, balance: BigNumber, callback: () => void = _.noop): void { const errorMsg = this._validate(amount, balance); this.props.onErrorMsgChange(errorMsg); diff --git a/packages/website/ts/components/inputs/eth_amount_input.tsx b/packages/website/ts/components/inputs/eth_amount_input.tsx index 1f0f27410..552d4277a 100644 --- a/packages/website/ts/components/inputs/eth_amount_input.tsx +++ b/packages/website/ts/components/inputs/eth_amount_input.tsx @@ -14,9 +14,7 @@ interface EthAmountInputProps { onChange: ValidatedBigNumberCallback; onErrorMsgChange?: (errorMsg: React.ReactNode) => void; shouldShowIncompleteErrs: boolean; - onVisitBalancesPageClick?: () => void; shouldCheckBalance: boolean; - shouldHideVisitBalancesLink?: boolean; shouldShowErrs?: boolean; shouldShowUnderline?: boolean; style?: React.CSSProperties; @@ -46,8 +44,6 @@ export class EthAmountInput extends React.Component void; - onVisitBalancesPageClick?: () => void; lastForceTokenStateRefetch: number; shouldShowErrs?: boolean; shouldShowUnderline?: boolean; @@ -88,7 +87,6 @@ export class TokenAmountInput extends React.Component Date: Mon, 2 Jul 2018 17:26:48 -0700 Subject: Add media query abstraction around ScreenWidths and stop relayer grid hover effect on mobile --- packages/website/public/index.html | 12 +++++++++++- .../components/onboarding/unlock_wallet_onboarding_step.tsx | 2 +- .../ts/components/relayer_index/relayer_grid_tile.tsx | 4 ++++ packages/website/ts/types.ts | 7 ++++--- packages/website/ts/utils/utils.ts | 7 ++----- 5 files changed, 22 insertions(+), 10 deletions(-) (limited to 'packages') diff --git a/packages/website/public/index.html b/packages/website/public/index.html index 4c0985c71..c7a40875f 100644 --- a/packages/website/public/index.html +++ b/packages/website/public/index.html @@ -70,7 +70,17 @@ })(document, 'script', 'twitter-wjs'); - + + diff --git a/packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx b/packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx index 0039aa545..4ed7137d4 100644 --- a/packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx +++ b/packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx @@ -10,7 +10,7 @@ export const UnlockWalletOnboardingStep: React.StatelessComponent - Unlock your metamask extension to get started. + Unlock your MetaMask extension to get started.
); diff --git a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx index b26bf512b..20594e5ca 100644 --- a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx +++ b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx @@ -9,6 +9,7 @@ import { Container } from 'ts/components/ui/container'; import { Image } from 'ts/components/ui/image'; import { Island } from 'ts/components/ui/island'; import { colors } from 'ts/style/colors'; +import { media } from 'ts/style/media'; import { styled } from 'ts/style/theme'; import { WebsiteBackendRelayerInfo } from 'ts/types'; import { utils } from 'ts/utils/utils'; @@ -111,6 +112,9 @@ const GridTile = styled(PlainGridTile)` &:hover { transform: translate(0px, -3px); } + ${media.small` + transform: none; + `}; `; interface SectionProps { diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 498a0a5b8..e8fdbc255 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -215,10 +215,11 @@ export interface ContractEvent { } export type ValidatedBigNumberCallback = (isValid: boolean, amount?: BigNumber) => void; +// Associated values are in `em` units export enum ScreenWidths { - Sm = 'SM', - Md = 'MD', - Lg = 'LG', + Sm = 40, + Md = 52, + Lg = 64, } export enum AlertTypes { diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts index 726e1815f..73dacc1d6 100644 --- a/packages/website/ts/utils/utils.ts +++ b/packages/website/ts/utils/utils.ts @@ -27,9 +27,6 @@ import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import * as u2f from 'ts/vendor/u2f_api'; -const LG_MIN_EM = 64; -const MD_MIN_EM = 52; - const isDogfood = (): boolean => _.includes(window.location.href, configs.DOMAIN_DOGFOOD); export const utils = { @@ -134,9 +131,9 @@ export const utils = { // This logic mirrors the CSS media queries in BassCSS for the `lg-`, `md-` and `sm-` CSS // class prefixes. Do not edit these. - if (widthInEm > LG_MIN_EM) { + if (widthInEm > ScreenWidths.Lg) { return ScreenWidths.Lg; - } else if (widthInEm > MD_MIN_EM) { + } else if (widthInEm > ScreenWidths.Md) { return ScreenWidths.Md; } else { return ScreenWidths.Sm; -- cgit v1.2.3 From fe68114f3921a52fd6b6aa6cfef8d5c325499711 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 2 Jul 2018 17:56:37 -0700 Subject: Use new lock svg --- packages/website/public/images/lock_icon.svg | 3 +++ packages/website/ts/components/top_bar/provider_display.tsx | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 packages/website/public/images/lock_icon.svg (limited to 'packages') diff --git a/packages/website/public/images/lock_icon.svg b/packages/website/public/images/lock_icon.svg new file mode 100644 index 000000000..83e8191a1 --- /dev/null +++ b/packages/website/public/images/lock_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 8743e4320..ae3be6436 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -3,7 +3,6 @@ import * as _ from 'lodash'; import CircularProgress from 'material-ui/CircularProgress'; import RaisedButton from 'material-ui/RaisedButton'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; -import Lock from 'material-ui/svg-icons/action/lock'; import * as React from 'react'; import { Blockchain } from 'ts/blockchain'; @@ -12,6 +11,7 @@ import { AccountConnection } from 'ts/components/ui/account_connection'; import { Container } from 'ts/components/ui/container'; import { DropDown } from 'ts/components/ui/drop_down'; import { Identicon } from 'ts/components/ui/identicon'; +import { Image } from 'ts/components/ui/image'; import { Island } from 'ts/components/ui/island'; import { Text } from 'ts/components/ui/text'; import { Dispatcher } from 'ts/redux/dispatcher'; @@ -154,7 +154,7 @@ export class ProviderDisplay extends React.Component; case AccountState.Locked: - return ; + return ; case AccountState.Disconnected: return ; default: -- cgit v1.2.3 From a31f7a5112e9a74a64dd4079a08c0c749e3ffaeb Mon Sep 17 00:00:00 2001 From: fragosti Date: Mon, 2 Jul 2018 18:12:08 -0700 Subject: Implement fixed position onboarding option --- .../ts/components/onboarding/onboarding_flow.tsx | 55 ++++++++++++++++------ .../onboarding/portal_onboarding_flow.tsx | 45 ++++++++++-------- 2 files changed, 67 insertions(+), 33 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 1f4c6df82..9abbc1c82 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -1,18 +1,35 @@ +import * as _ from 'lodash'; import * as React from 'react'; import { Placement, Popper, PopperChildrenProps } from 'react-popper'; import { OnboardingCard } from 'ts/components/onboarding/onboarding_card'; +import { PointerDirection } from 'ts/components/ui/pointer'; import { ContinueButtonDisplay, OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; import { Animation } from 'ts/components/ui/animation'; import { Container } from 'ts/components/ui/container'; import { Overlay } from 'ts/components/ui/overlay'; import { zIndex } from 'ts/style/z_index'; -export interface Step { +export interface FixedPositionSettings { + type: 'fixed'; + top?: string; + bottom?: string; + left?: string; + right?: string; + pointerDirection?: PointerDirection; +} + +export interface TargetPositionSettings { + type: 'target'; target: string; + placement: Placement; +} + +export interface Step { + // Provide either a CSS selector, or fixed position settings. Only applies to desktop. + position: TargetPositionSettings | FixedPositionSettings; title?: string; content: React.ReactNode; - placement?: Placement; shouldHideBackButton?: boolean; shouldHideNextButton?: boolean; continueButtonDisplay?: ContinueButtonDisplay; @@ -40,18 +57,30 @@ export class OnboardingFlow extends React.Component { return null; } let onboardingElement = null; + const currentStep = this._getCurrentStep(); if (this.props.isMobile) { - onboardingElement = {this._renderOnboardignCard()}; - } else { + onboardingElement = {this._renderOnboardingCard()}; + } else if (currentStep.position.type === 'target') { + const { placement, target } = currentStep.position; onboardingElement = ( - + {this._renderPopperChildren.bind(this)} ); + } else if (currentStep.position.type === 'fixed') { + const { top, right, bottom, left, pointerDirection } = currentStep.position; + onboardingElement = ( + + {this._renderToolTip(pointerDirection)} + + ); } if (this.props.disableOverlay) { return onboardingElement; @@ -63,9 +92,6 @@ export class OnboardingFlow extends React.Component {
); } - private _getElementForStep(): Element { - return document.querySelector(this._getCurrentStep().target); - } private _renderPopperChildren(props: PopperChildrenProps): React.ReactNode { const customStyles = { zIndex: zIndex.aboveOverlay }; // On re-render, we want to re-center the popper. @@ -76,7 +102,7 @@ export class OnboardingFlow extends React.Component {
); } - private _renderToolTip(): React.ReactNode { + private _renderToolTip(pointerDirection?: PointerDirection): React.ReactNode { const { steps, stepIndex } = this.props; const step = steps[stepIndex]; const isLastStep = steps.length - 1 === stepIndex; @@ -94,12 +120,13 @@ export class OnboardingFlow extends React.Component { continueButtonDisplay={step.continueButtonDisplay} continueButtonText={step.continueButtonText} onContinueButtonClick={step.onContinueButtonClick} + pointerDirection={pointerDirection} /> ); } - private _renderOnboardignCard(): React.ReactNode { + private _renderOnboardingCard(): React.ReactNode { const { steps, stepIndex } = this.props; const step = steps[stepIndex]; const isLastStep = steps.length - 1 === stepIndex; diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 6d8007659..f83736aae 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -9,7 +9,12 @@ import { AddEthOnboardingStep } from 'ts/components/onboarding/add_eth_onboardin import { CongratsOnboardingStep } from 'ts/components/onboarding/congrats_onboarding_step'; import { InstallWalletOnboardingStep } from 'ts/components/onboarding/install_wallet_onboarding_step'; import { IntroOnboardingStep } from 'ts/components/onboarding/intro_onboarding_step'; -import { OnboardingFlow, Step } from 'ts/components/onboarding/onboarding_flow'; +import { + OnboardingFlow, + Step, + TargetPositionSettings, + FixedPositionSettings, +} from 'ts/components/onboarding/onboarding_flow'; import { SetAllowancesOnboardingStep } from 'ts/components/onboarding/set_allowances_onboarding_step'; import { UnlockWalletOnboardingStep } from 'ts/components/onboarding/unlock_wallet_onboarding_step'; import { @@ -79,56 +84,61 @@ class PlainPortalOnboardingFlow extends React.Component, - placement: 'right', shouldHideBackButton: true, shouldHideNextButton: true, }, { - target: '.wallet', + position: underMetamaskExtension, title: '0x Ecosystem Setup', content: , - placement: 'right', shouldHideBackButton: true, shouldHideNextButton: true, }, { - target: '.wallet', + position: nextToWalletPosition, title: '0x Ecosystem Account Setup', content: , - placement: 'right', shouldHideBackButton: true, continueButtonDisplay: 'enabled', }, { - target: '.wallet', + position: nextToWalletPosition, title: 'Step 1: Add ETH', content: ( ), - placement: 'right', continueButtonDisplay: this._userHasVisibleEth() ? 'enabled' : 'disabled', }, { - target: '.wallet', + position: nextToWalletPosition, title: 'Step 2: Wrap ETH', content: , - placement: 'right', continueButtonDisplay: 'enabled', }, { - target: '.wallet', + position: nextToWalletPosition, title: 'Step 2: Wrap ETH', content: , - placement: 'right', continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled', }, { - target: '.wallet', + position: nextToWalletPosition, title: 'Step 2: Wrap ETH', content: ( ), - placement: 'right', continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled', }, { - target: '.wallet', + position: nextToWalletPosition, title: 'Step 3: Unlock Tokens', content: ( ), - placement: 'right', continueButtonDisplay: this._doesUserHaveAllowancesForWethAndZrx() ? 'enabled' : 'disabled', }, { - target: '.wallet', + position: nextToWalletPosition, title: '🎉 The Ecosystem Awaits', content: , - placement: 'right', continueButtonDisplay: 'enabled', shouldHideNextButton: true, continueButtonText: 'Enter the 0x Ecosystem', -- cgit v1.2.3 From f62044c1e3f35e0985724ebc1bac3a9b23dc2c2e Mon Sep 17 00:00:00 2001 From: fragosti Date: Mon, 2 Jul 2018 18:14:21 -0700 Subject: Add media file and remove stray comment --- .../ts/components/onboarding/portal_onboarding_flow.tsx | 2 -- packages/website/ts/style/media.ts | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 packages/website/ts/style/media.ts (limited to 'packages') diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 6d8007659..c8786da13 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -45,8 +45,6 @@ class PlainPortalOnboardingFlow extends React.Component void; public componentDidMount(): void { this._adjustStepIfShould(); - // Wait until the step is adjusted to decide whether we should show onboarding. - // setTimeout(this._autoStartOnboardingIfShould.bind(this), 1000); // If there is a route change, just close onboarding. this._unlisten = this.props.history.listen(() => this.props.updateIsRunning(false)); } diff --git a/packages/website/ts/style/media.ts b/packages/website/ts/style/media.ts new file mode 100644 index 000000000..2f8551f34 --- /dev/null +++ b/packages/website/ts/style/media.ts @@ -0,0 +1,15 @@ +import * as _ from 'lodash'; +import { css } from 'ts/style/theme'; +import { ScreenWidths } from 'ts/types'; + +const generateMediaWrapper = (screenWidth: ScreenWidths) => (...args: any[]) => css` + @media (max-width: ${screenWidth}) { + ${css.apply(css, args)}; + } +`; + +export const media = { + small: generateMediaWrapper(ScreenWidths.Sm), + medium: generateMediaWrapper(ScreenWidths.Md), + large: generateMediaWrapper(ScreenWidths.Lg), +}; -- cgit v1.2.3 From 8929543b550cad73987a795d97bbe7dee6bb0d45 Mon Sep 17 00:00:00 2001 From: fragosti Date: Mon, 2 Jul 2018 18:15:41 -0700 Subject: Add end comment to hotjar tracking code --- packages/website/public/index.html | 1 + 1 file changed, 1 insertion(+) (limited to 'packages') diff --git a/packages/website/public/index.html b/packages/website/public/index.html index c7a40875f..060f2c3c2 100644 --- a/packages/website/public/index.html +++ b/packages/website/public/index.html @@ -81,6 +81,7 @@ a.appendChild(r); })(window, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv='); + -- cgit v1.2.3 From 6fc5c0cd460cf1cb8ac8fbe86e6d2fdbaa23ffe1 Mon Sep 17 00:00:00 2001 From: fragosti Date: Mon, 2 Jul 2018 18:36:41 -0700 Subject: Remove unused import --- packages/website/ts/style/media.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages') diff --git a/packages/website/ts/style/media.ts b/packages/website/ts/style/media.ts index 2f8551f34..3c992eb9f 100644 --- a/packages/website/ts/style/media.ts +++ b/packages/website/ts/style/media.ts @@ -1,4 +1,3 @@ -import * as _ from 'lodash'; import { css } from 'ts/style/theme'; import { ScreenWidths } from 'ts/types'; -- cgit v1.2.3 From 5b64b3ea937326978b5742ec1b3692ebe5c41991 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Mon, 2 Jul 2018 18:44:37 -0700 Subject: Improve robustness of revert reason assertions --- .../contracts/test/asset_proxy/authorizable.ts | 18 +-- packages/contracts/test/asset_proxy/proxies.ts | 16 +- packages/contracts/test/exchange/core.ts | 36 ++--- packages/contracts/test/exchange/dispatcher.ts | 8 +- packages/contracts/test/exchange/match_orders.ts | 12 +- .../contracts/test/exchange/signature_validator.ts | 10 +- packages/contracts/test/exchange/transactions.ts | 16 +- packages/contracts/test/exchange/wrapper.ts | 12 +- packages/contracts/test/libraries/lib_bytes.ts | 46 +++--- .../contracts/test/multisig/asset_proxy_owner.ts | 21 +-- .../test/multisig/multi_sig_with_time_lock.ts | 8 +- packages/contracts/test/token_registry.ts | 32 ++-- packages/contracts/test/tokens/ether_token.ts | 4 +- .../test/tokens/unlimited_allowance_token.ts | 8 +- packages/contracts/test/utils/assertions.ts | 161 +++++++++++++-------- packages/contracts/test/utils/constants.ts | 1 - .../test/utils/core_combinatorial_utils.ts | 4 +- packages/dev-utils/src/blockchain_lifecycle.ts | 22 +-- packages/migrations/artifacts/2.0.0/ZRXToken.json | 32 ++-- packages/web3-wrapper/src/index.ts | 2 +- packages/web3-wrapper/src/web3_wrapper.ts | 21 +++ 21 files changed, 269 insertions(+), 221 deletions(-) (limited to 'packages') diff --git a/packages/contracts/test/asset_proxy/authorizable.ts b/packages/contracts/test/asset_proxy/authorizable.ts index 5a0586c28..e99c6cee3 100644 --- a/packages/contracts/test/asset_proxy/authorizable.ts +++ b/packages/contracts/test/asset_proxy/authorizable.ts @@ -5,7 +5,7 @@ import * as chai from 'chai'; import { MixinAuthorizableContract } from '../../generated_contract_wrappers/mixin_authorizable'; import { artifacts } from '../utils/artifacts'; -import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions'; +import { expectTransactionFailedAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper'; @@ -44,7 +44,7 @@ describe('Authorizable', () => { }); describe('addAuthorizedAddress', () => { it('should throw if not called by owner', async () => { - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( authorizable.addAuthorizedAddress.sendTransactionAsync(notOwner, { from: notOwner }), RevertReason.OnlyContractOwner, ); @@ -62,7 +62,7 @@ describe('Authorizable', () => { await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), RevertReason.TargetAlreadyAuthorized, ); @@ -75,7 +75,7 @@ describe('Authorizable', () => { await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( authorizable.removeAuthorizedAddress.sendTransactionAsync(address, { from: notOwner, }), @@ -99,7 +99,7 @@ describe('Authorizable', () => { }); it('should throw if owner attempts to remove an address that is not authorized', async () => { - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( authorizable.removeAuthorizedAddress.sendTransactionAsync(address, { from: owner, }), @@ -115,7 +115,7 @@ describe('Authorizable', () => { constants.AWAIT_TRANSACTION_MINED_MS, ); const index = new BigNumber(0); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, { from: notOwner, }), @@ -128,7 +128,7 @@ describe('Authorizable', () => { constants.AWAIT_TRANSACTION_MINED_MS, ); const index = new BigNumber(1); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, { from: owner, }), @@ -137,7 +137,7 @@ describe('Authorizable', () => { }); it('should throw if owner attempts to remove an address that is not authorized', async () => { const index = new BigNumber(0); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, { from: owner, }), @@ -156,7 +156,7 @@ describe('Authorizable', () => { constants.AWAIT_TRANSACTION_MINED_MS, ); const address1Index = new BigNumber(0); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address2, address1Index, { from: owner, }), diff --git a/packages/contracts/test/asset_proxy/proxies.ts b/packages/contracts/test/asset_proxy/proxies.ts index fc1e53352..bf9f9bc3e 100644 --- a/packages/contracts/test/asset_proxy/proxies.ts +++ b/packages/contracts/test/asset_proxy/proxies.ts @@ -17,7 +17,7 @@ import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_pr import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy'; import { IAssetProxyContract } from '../../generated_contract_wrappers/i_asset_proxy'; import { artifacts } from '../utils/artifacts'; -import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions'; +import { expectTransactionFailedAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { ERC20Wrapper } from '../utils/erc20_wrapper'; @@ -184,7 +184,7 @@ describe('Asset Transfer Proxies', () => { constants.AWAIT_TRANSACTION_MINED_MS, ); // Perform a transfer; expect this to fail. - return expectRevertReasonOrAlwaysFailingTransactionAsync( + await expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc20Proxy.address, data, @@ -205,7 +205,7 @@ describe('Asset Transfer Proxies', () => { takerAddress, amount, ); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + await expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc20Proxy.address, data, @@ -344,7 +344,7 @@ describe('Asset Transfer Proxies', () => { erc20Proxy.address, // the ERC20 proxy does not have an ERC721 receiver amount, ); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc721Proxy.address, data, @@ -369,7 +369,7 @@ describe('Asset Transfer Proxies', () => { takerAddress, amount, ); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc721Proxy.address, data, @@ -393,7 +393,7 @@ describe('Asset Transfer Proxies', () => { takerAddress, amount, ); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc721Proxy.address, data, @@ -421,7 +421,7 @@ describe('Asset Transfer Proxies', () => { takerAddress, amount, ); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc721Proxy.address, data, @@ -442,7 +442,7 @@ describe('Asset Transfer Proxies', () => { takerAddress, amount, ); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc721Proxy.address, data, diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index db56623f9..4e70893fc 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -14,7 +14,7 @@ import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_pr import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy'; import { CancelContractEventArgs, ExchangeContract } from '../../generated_contract_wrappers/exchange'; import { artifacts } from '../utils/artifacts'; -import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions'; +import { expectTransactionFailedAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { ERC20Wrapper } from '../utils/erc20_wrapper'; @@ -144,7 +144,7 @@ describe('Exchange core', () => { const invalidSigBuff = Buffer.concat([v, invalidR, invalidS, signatureType]); const invalidSigHex = `0x${invalidSigBuff.toString('hex')}`; signedOrder.signature = invalidSigHex; - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, takerAddress), RevertReason.InvalidOrderSignature, ); @@ -153,7 +153,7 @@ describe('Exchange core', () => { it('should throw if no value is filled', async () => { signedOrder = orderFactory.newSignedOrder(); await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, takerAddress), RevertReason.OrderUnfillable, ); @@ -167,7 +167,7 @@ describe('Exchange core', () => { }); it('should throw if not sent by maker', async () => { - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.cancelOrderAsync(signedOrder, takerAddress), RevertReason.InvalidMaker, ); @@ -178,7 +178,7 @@ describe('Exchange core', () => { makerAssetAmount: new BigNumber(0), }); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress), RevertReason.OrderUnfillable, ); @@ -189,7 +189,7 @@ describe('Exchange core', () => { takerAssetAmount: new BigNumber(0), }); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress), RevertReason.OrderUnfillable, ); @@ -197,7 +197,7 @@ describe('Exchange core', () => { it('should be able to cancel a full order', async () => { await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: signedOrder.takerAssetAmount.div(2), }), @@ -222,7 +222,7 @@ describe('Exchange core', () => { it('should throw if already cancelled', async () => { await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress), RevertReason.OrderUnfillable, ); @@ -232,7 +232,7 @@ describe('Exchange core', () => { signedOrder = orderFactory.newSignedOrder({ expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)), }); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress), RevertReason.OrderUnfillable, ); @@ -250,7 +250,7 @@ describe('Exchange core', () => { }); const fillTakerAssetAmount2 = new BigNumber(1); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillTakerAssetAmount2, }), @@ -264,7 +264,7 @@ describe('Exchange core', () => { const orderEpoch = new BigNumber(1); await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress); const lesserOrderEpoch = new BigNumber(0); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.cancelOrdersUpToAsync(lesserOrderEpoch, makerAddress), RevertReason.InvalidNewOrderEpoch, ); @@ -273,7 +273,7 @@ describe('Exchange core', () => { it('should fail to set orderEpoch equal to existing orderEpoch', async () => { const orderEpoch = new BigNumber(1); await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress), RevertReason.InvalidNewOrderEpoch, ); @@ -363,7 +363,7 @@ describe('Exchange core', () => { expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress); // Call Exchange const takerAssetFillAmount = signedOrder.takerAssetAmount; - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }), RevertReason.TransferFailed, ); @@ -386,7 +386,7 @@ describe('Exchange core', () => { expect(initialOwnerTakerAsset).to.be.bignumber.not.equal(takerAddress); // Call Exchange const takerAssetFillAmount = signedOrder.takerAssetAmount; - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }), RevertReason.TransferFailed, ); @@ -409,7 +409,7 @@ describe('Exchange core', () => { expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress); // Call Exchange const takerAssetFillAmount = signedOrder.takerAssetAmount; - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }), RevertReason.InvalidAmount, ); @@ -432,7 +432,7 @@ describe('Exchange core', () => { expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress); // Call Exchange const takerAssetFillAmount = signedOrder.takerAssetAmount; - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }), RevertReason.InvalidAmount, ); @@ -449,7 +449,7 @@ describe('Exchange core', () => { }); // Call Exchange const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }), RevertReason.RoundingError, ); @@ -475,7 +475,7 @@ describe('Exchange core', () => { expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress); // Call Exchange const takerAssetFillAmount = signedOrder.takerAssetAmount; - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }), RevertReason.LengthGreaterThan131Required, ); diff --git a/packages/contracts/test/exchange/dispatcher.ts b/packages/contracts/test/exchange/dispatcher.ts index afbf958d9..94ada1ef2 100644 --- a/packages/contracts/test/exchange/dispatcher.ts +++ b/packages/contracts/test/exchange/dispatcher.ts @@ -14,7 +14,7 @@ import { TestAssetProxyDispatcherContract, } from '../../generated_contract_wrappers/test_asset_proxy_dispatcher'; import { artifacts } from '../utils/artifacts'; -import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions'; +import { expectTransactionFailedAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { ERC20Wrapper } from '../utils/erc20_wrapper'; @@ -129,7 +129,7 @@ describe('AssetProxyDispatcher', () => { txDefaults, ); // Register new ERC20 Transfer Proxy contract - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(newErc20TransferProxy.address, { from: owner, }), @@ -138,7 +138,7 @@ describe('AssetProxyDispatcher', () => { }); it('should throw if requesting address is not owner', async () => { - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, { from: notOwner }), RevertReason.OnlyContractOwner, ); @@ -210,7 +210,7 @@ describe('AssetProxyDispatcher', () => { const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(10); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync( encodedAssetData, makerAddress, diff --git a/packages/contracts/test/exchange/match_orders.ts b/packages/contracts/test/exchange/match_orders.ts index 0d07d156f..90406415f 100644 --- a/packages/contracts/test/exchange/match_orders.ts +++ b/packages/contracts/test/exchange/match_orders.ts @@ -12,7 +12,7 @@ import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_pr import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy'; import { ExchangeContract } from '../../generated_contract_wrappers/exchange'; import { artifacts } from '../utils/artifacts'; -import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions'; +import { expectTransactionFailedAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { ERC20Wrapper } from '../utils/erc20_wrapper'; @@ -602,7 +602,7 @@ describe('matchOrders', () => { // Cancel left order await exchangeWrapper.cancelOrderAsync(signedOrderLeft, signedOrderLeft.makerAddress); // Match orders - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress), RevertReason.OrderUnfillable, ); @@ -627,7 +627,7 @@ describe('matchOrders', () => { // Cancel right order await exchangeWrapper.cancelOrderAsync(signedOrderRight, signedOrderRight.makerAddress); // Match orders - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress), RevertReason.OrderUnfillable, ); @@ -650,7 +650,7 @@ describe('matchOrders', () => { feeRecipientAddress: feeRecipientAddressRight, }); // Match orders - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress), RevertReason.NegativeSpreadRequired, ); @@ -673,7 +673,7 @@ describe('matchOrders', () => { feeRecipientAddress: feeRecipientAddressRight, }); // Match orders - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress), // We are assuming assetData fields of the right order are the // reverse of the left order, rather than checking equality. This @@ -702,7 +702,7 @@ describe('matchOrders', () => { feeRecipientAddress: feeRecipientAddressRight, }); // Match orders - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress), RevertReason.InvalidOrderSignature, ); diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index 1db7dfc6d..c44d22479 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -13,7 +13,7 @@ import { TestValidatorContract } from '../../generated_contract_wrappers/test_va import { TestWalletContract } from '../../generated_contract_wrappers/test_wallet'; import { addressUtils } from '../utils/address_utils'; import { artifacts } from '../utils/artifacts'; -import { expectRevertOrOtherErrorAsync } from '../utils/assertions'; +import { expectContractCallFailed } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { LogDecoder } from '../utils/log_decoder'; @@ -101,7 +101,7 @@ describe('MixinSignatureValidator', () => { it('should revert when signature is empty', async () => { const emptySignature = '0x'; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, @@ -115,7 +115,7 @@ describe('MixinSignatureValidator', () => { const unsupportedSignatureType = SignatureType.NSignatureTypes; const unsupportedSignatureHex = `0x${unsupportedSignatureType}`; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, @@ -128,7 +128,7 @@ describe('MixinSignatureValidator', () => { it('should revert when SignatureType=Illegal', async () => { const unsupportedSignatureHex = `0x${SignatureType.Illegal}`; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, @@ -155,7 +155,7 @@ describe('MixinSignatureValidator', () => { const signatureBuffer = Buffer.concat([fillerData, signatureType]); const signatureHex = ethUtil.bufferToHex(signatureBuffer); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, diff --git a/packages/contracts/test/exchange/transactions.ts b/packages/contracts/test/exchange/transactions.ts index 4f8b49e0e..959d79517 100644 --- a/packages/contracts/test/exchange/transactions.ts +++ b/packages/contracts/test/exchange/transactions.ts @@ -11,7 +11,7 @@ import { ExchangeContract } from '../../generated_contract_wrappers/exchange'; import { ExchangeWrapperContract } from '../../generated_contract_wrappers/exchange_wrapper'; import { WhitelistContract } from '../../generated_contract_wrappers/whitelist'; import { artifacts } from '../utils/artifacts'; -import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions'; +import { expectTransactionFailedAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { ERC20Wrapper } from '../utils/erc20_wrapper'; @@ -134,7 +134,7 @@ describe('Exchange transactions', () => { }); it('should throw if not called by specified sender', async () => { - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.executeTransactionAsync(signedTx, takerAddress), RevertReason.FailedExecution, ); @@ -177,7 +177,7 @@ describe('Exchange transactions', () => { it('should throw if the a 0x transaction with the same transactionHash has already been executed', async () => { await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.executeTransactionAsync(signedTx, senderAddress), RevertReason.InvalidTxHash, ); @@ -197,7 +197,7 @@ describe('Exchange transactions', () => { }); it('should throw if not called by specified sender', async () => { - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.executeTransactionAsync(signedTx, makerAddress), RevertReason.FailedExecution, ); @@ -205,7 +205,7 @@ describe('Exchange transactions', () => { it('should cancel the order when signed by maker and called by sender', async () => { await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrderAsync(signedOrder, senderAddress), RevertReason.OrderUnfillable, ); @@ -250,7 +250,7 @@ describe('Exchange transactions', () => { signedOrder.signature, ); const signedFillTx = takerTransactionFactory.newSignedTransaction(fillData); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapperContract.fillOrder.sendTransactionAsync( orderWithoutExchangeAddress, takerAssetFillAmount, @@ -370,7 +370,7 @@ describe('Exchange transactions', () => { orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder); const takerAssetFillAmount = signedOrder.takerAssetAmount; const salt = generatePseudoRandomSalt(); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( whitelist.fillOrderIfWhitelisted.sendTransactionAsync( orderWithoutExchangeAddress, takerAssetFillAmount, @@ -392,7 +392,7 @@ describe('Exchange transactions', () => { orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder); const takerAssetFillAmount = signedOrder.takerAssetAmount; const salt = generatePseudoRandomSalt(); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( whitelist.fillOrderIfWhitelisted.sendTransactionAsync( orderWithoutExchangeAddress, takerAssetFillAmount, diff --git a/packages/contracts/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts index 7942f7695..69f374e46 100644 --- a/packages/contracts/test/exchange/wrapper.ts +++ b/packages/contracts/test/exchange/wrapper.ts @@ -12,7 +12,7 @@ import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_pr import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy'; import { ExchangeContract } from '../../generated_contract_wrappers/exchange'; import { artifacts } from '../utils/artifacts'; -import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions'; +import { expectTransactionFailedAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { ERC20Wrapper } from '../utils/erc20_wrapper'; @@ -174,7 +174,7 @@ describe('Exchange wrappers', () => { expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)), }); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress), RevertReason.OrderUnfillable, ); @@ -187,7 +187,7 @@ describe('Exchange wrappers', () => { takerAssetFillAmount: signedOrder.takerAssetAmount.div(2), }); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress), RevertReason.CompleteFillFailed, ); @@ -500,7 +500,7 @@ describe('Exchange wrappers', () => { await exchangeWrapper.fillOrKillOrderAsync(signedOrders[0], takerAddress); - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.batchFillOrKillOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmounts, }), @@ -703,7 +703,7 @@ describe('Exchange wrappers', () => { orderFactory.newSignedOrder(), ]; - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.marketSellOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18), }), @@ -921,7 +921,7 @@ describe('Exchange wrappers', () => { orderFactory.newSignedOrder(), ]; - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( exchangeWrapper.marketBuyOrdersAsync(signedOrders, takerAddress, { makerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18), }), diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index 963b51b8f..c80b61e19 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -9,7 +9,7 @@ import * as _ from 'lodash'; import { TestLibBytesContract } from '../../generated_contract_wrappers/test_lib_bytes'; import { artifacts } from '../utils/artifacts'; -import { expectRevertOrOtherErrorAsync } from '../utils/assertions'; +import { expectContractCallFailed } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper'; @@ -100,7 +100,7 @@ describe('LibBytes', () => { describe('popLastByte', () => { it('should revert if length is 0', async () => { - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicPopLastByte.callAsync(constants.NULL_BYTES), RevertReason.LibBytesGreaterThanZeroLengthRequired, ); @@ -116,7 +116,7 @@ describe('LibBytes', () => { describe('popLast20Bytes', () => { it('should revert if length is less than 20', async () => { - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicPopLast20Bytes.callAsync(byteArrayShorterThan20Bytes), RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); @@ -184,7 +184,7 @@ describe('LibBytes', () => { describe('deepCopyBytes', () => { it('should revert if dest is shorter than source', async () => { - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicDeepCopyBytes.callAsync(byteArrayShorterThan32Bytes, byteArrayLongerThan32Bytes), RevertReason.LibBytesGreaterOrEqualToSourceBytesLengthRequired, ); @@ -237,7 +237,7 @@ describe('LibBytes', () => { it('should fail if the byte array is too short to hold an address', async () => { const shortByteArray = '0xabcdef'; const offset = new BigNumber(0); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadAddress.callAsync(shortByteArray, offset), RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); @@ -245,7 +245,7 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => { const byteArray = testAddress; const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadAddress.callAsync(byteArray, badOffset), RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); @@ -281,7 +281,7 @@ describe('LibBytes', () => { }); it('should fail if the byte array is too short to hold an address', async () => { const offset = new BigNumber(0); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicWriteAddress.callAsync(byteArrayShorterThan20Bytes, offset, testAddress), RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); @@ -289,7 +289,7 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => { const byteArray = byteArrayLongerThan32Bytes; const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicWriteAddress.callAsync(byteArray, badOffset, testAddress), RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); @@ -313,14 +313,14 @@ describe('LibBytes', () => { }); it('should fail if the byte array is too short to hold a bytes32', async () => { const offset = new BigNumber(0); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadBytes32.callAsync(byteArrayShorterThan32Bytes, offset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); }); it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadBytes32.callAsync(testBytes32, badOffset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -356,7 +356,7 @@ describe('LibBytes', () => { }); it('should fail if the byte array is too short to hold a bytes32', async () => { const offset = new BigNumber(0); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicWriteBytes32.callAsync(byteArrayShorterThan32Bytes, offset, testBytes32), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -364,7 +364,7 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => { const byteArray = byteArrayLongerThan32Bytes; const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicWriteBytes32.callAsync(byteArray, badOffset, testBytes32), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -392,7 +392,7 @@ describe('LibBytes', () => { }); it('should fail if the byte array is too short to hold a uint256', async () => { const offset = new BigNumber(0); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadUint256.callAsync(byteArrayShorterThan32Bytes, offset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -402,7 +402,7 @@ describe('LibBytes', () => { const testUint256AsBuffer = ethUtil.toBuffer(formattedTestUint256); const byteArray = ethUtil.bufferToHex(testUint256AsBuffer); const badOffset = new BigNumber(testUint256AsBuffer.byteLength); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadUint256.callAsync(byteArray, badOffset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -442,7 +442,7 @@ describe('LibBytes', () => { }); it('should fail if the byte array is too short to hold a uint256', async () => { const offset = new BigNumber(0); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicWriteUint256.callAsync(byteArrayShorterThan32Bytes, offset, testUint256), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -450,7 +450,7 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold a uint256', async () => { const byteArray = byteArrayLongerThan32Bytes; const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicWriteUint256.callAsync(byteArray, badOffset, testUint256), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -461,7 +461,7 @@ describe('LibBytes', () => { // AssertionError: expected promise to be rejected with an error including 'revert' but it was fulfilled with '0x08c379a0' it('should revert if byte array has a length < 4', async () => { const byteArrayLessThan4Bytes = '0x010101'; - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadBytes4.callAsync(byteArrayLessThan4Bytes, new BigNumber(0)), RevertReason.LibBytesGreaterOrEqualTo4LengthRequired, ); @@ -516,28 +516,28 @@ describe('LibBytes', () => { it('should fail if the byte array is too short to hold the length of a nested byte array', async () => { // The length of the nested array is 32 bytes. By storing less than 32 bytes, a length cannot be read. const offset = new BigNumber(0); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, offset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); }); it('should fail if we store a nested byte array length, without a nested byte array', async () => { const offset = new BigNumber(0); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadBytesWithLength.callAsync(testBytes32, offset), RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired, ); }); it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(byteArrayShorterThan32Bytes).byteLength); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, badOffset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); }); it('should fail if the length between the offset and end of the byte array is too short to hold the nested byte array', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicReadBytesWithLength.callAsync(testBytes32, badOffset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -649,7 +649,7 @@ describe('LibBytes', () => { it('should fail if the byte array is too short to hold the length of a nested byte array', async () => { const offset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(1)); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, offset, longData), RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired, ); @@ -657,7 +657,7 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array)', async () => { const emptyByteArray = ethUtil.bufferToHex(new Buffer(shortTestBytesAsBuffer.byteLength)); const badOffset = new BigNumber(ethUtil.toBuffer(shortTestBytesAsBuffer).byteLength); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, badOffset, shortData), RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired, ); diff --git a/packages/contracts/test/multisig/asset_proxy_owner.ts b/packages/contracts/test/multisig/asset_proxy_owner.ts index cde86dd46..16231dfcb 100644 --- a/packages/contracts/test/multisig/asset_proxy_owner.ts +++ b/packages/contracts/test/multisig/asset_proxy_owner.ts @@ -14,8 +14,9 @@ import { MixinAuthorizableContract } from '../../generated_contract_wrappers/mix import { TestAssetProxyOwnerContract } from '../../generated_contract_wrappers/test_asset_proxy_owner'; import { artifacts } from '../utils/artifacts'; import { - expectRevertOrAlwaysFailingTransactionAsync, - expectRevertOrContractCallFailedAsync, + expectContractCallFailedWithoutReasonAsync, + expectContractCreationFailedWithoutReason, + expectTransactionFailedWithoutReasonAsync, } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; @@ -108,7 +109,7 @@ describe('AssetProxyOwner', () => { }); it('should throw if a null address is included in assetProxyContracts', async () => { const assetProxyContractAddresses = [erc20Proxy.address, constants.NULL_ADDRESS]; - return expectRevertOrAlwaysFailingTransactionAsync( + return expectContractCreationFailedWithoutReason( AssetProxyOwnerContract.deployFrom0xArtifactAsync( artifacts.AssetProxyOwner, provider, @@ -150,7 +151,7 @@ describe('AssetProxyOwner', () => { describe('registerAssetProxy', () => { it('should throw if not called by multisig', async () => { const isRegistered = true; - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( testAssetProxyOwner.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, isRegistered, { from: owners[0], }), @@ -277,7 +278,7 @@ describe('AssetProxyOwner', () => { ); const log = submitTxRes.logs[0] as LogWithDecodedArgs; const txId = log.args.transactionId; - return expectRevertOrContractCallFailedAsync( + return expectContractCallFailedWithoutReasonAsync( testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId), ); }); @@ -312,7 +313,7 @@ describe('AssetProxyOwner', () => { ); const log = submitTxRes.logs[0] as LogWithDecodedArgs; const txId = log.args.transactionId; - return expectRevertOrContractCallFailedAsync( + return expectContractCallFailedWithoutReasonAsync( testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId), ); }); @@ -332,7 +333,7 @@ describe('AssetProxyOwner', () => { const log = res.logs[0] as LogWithDecodedArgs; const txId = log.args.transactionId; - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { from: owners[1], }), @@ -354,7 +355,7 @@ describe('AssetProxyOwner', () => { await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { from: owners[1], }), @@ -376,7 +377,7 @@ describe('AssetProxyOwner', () => { await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { from: owners[1], }), @@ -433,7 +434,7 @@ describe('AssetProxyOwner', () => { const isExecuted = tx[3]; expect(isExecuted).to.equal(true); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { from: owners[1], }), diff --git a/packages/contracts/test/multisig/multi_sig_with_time_lock.ts b/packages/contracts/test/multisig/multi_sig_with_time_lock.ts index a746403d2..a7b99d867 100644 --- a/packages/contracts/test/multisig/multi_sig_with_time_lock.ts +++ b/packages/contracts/test/multisig/multi_sig_with_time_lock.ts @@ -8,7 +8,7 @@ import { SubmissionContractEventArgs, } from '../../generated_contract_wrappers/multi_sig_wallet_with_time_lock'; import { artifacts } from '../utils/artifacts'; -import { expectRevertOrAlwaysFailingTransactionAsync } from '../utils/assertions'; +import { expectTransactionFailedWithoutReasonAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { increaseTimeAndMineBlockAsync } from '../utils/increase_time'; @@ -67,7 +67,7 @@ describe('MultiSigWalletWithTimeLock', () => { }); it('should throw when not called by wallet', async () => { - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( multiSig.changeTimeLock.sendTransactionAsync(SECONDS_TIME_LOCKED, { from: owners[0] }), ); }); @@ -78,7 +78,7 @@ describe('MultiSigWalletWithTimeLock', () => { const res = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]); const log = res.logs[0] as LogWithDecodedArgs; const txId = log.args.transactionId; - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }), ); }); @@ -147,7 +147,7 @@ describe('MultiSigWalletWithTimeLock', () => { }); it('should throw if it has enough confirmations but is not past the time lock', async () => { - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }), ); }); diff --git a/packages/contracts/test/token_registry.ts b/packages/contracts/test/token_registry.ts index 32f8cdee3..7cc43be9b 100644 --- a/packages/contracts/test/token_registry.ts +++ b/packages/contracts/test/token_registry.ts @@ -7,7 +7,7 @@ import * as _ from 'lodash'; import { TokenRegistryContract } from '../generated_contract_wrappers/token_registry'; import { artifacts } from './utils/artifacts'; -import { expectRevertOrAlwaysFailingTransactionAsync } from './utils/assertions'; +import { expectTransactionFailedWithoutReasonAsync } from './utils/assertions'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; import { TokenRegWrapper } from './utils/token_registry_wrapper'; @@ -75,7 +75,7 @@ describe('TokenRegistry', () => { describe('addToken', () => { it('should throw when not called by owner', async () => { - return expectRevertOrAlwaysFailingTransactionAsync(tokenRegWrapper.addTokenAsync(token1, notOwner)); + return expectTransactionFailedWithoutReasonAsync(tokenRegWrapper.addTokenAsync(token1, notOwner)); }); it('should add token metadata when called by owner', async () => { @@ -87,20 +87,18 @@ describe('TokenRegistry', () => { it('should throw if token already exists', async () => { await tokenRegWrapper.addTokenAsync(token1, owner); - return expectRevertOrAlwaysFailingTransactionAsync(tokenRegWrapper.addTokenAsync(token1, owner)); + return expectTransactionFailedWithoutReasonAsync(tokenRegWrapper.addTokenAsync(token1, owner)); }); it('should throw if token address is null', async () => { - return expectRevertOrAlwaysFailingTransactionAsync(tokenRegWrapper.addTokenAsync(nullToken, owner)); + return expectTransactionFailedWithoutReasonAsync(tokenRegWrapper.addTokenAsync(nullToken, owner)); }); it('should throw if name already exists', async () => { await tokenRegWrapper.addTokenAsync(token1, owner); const duplicateNameToken = _.assign({}, token2, { name: token1.name }); - return expectRevertOrAlwaysFailingTransactionAsync( - tokenRegWrapper.addTokenAsync(duplicateNameToken, owner), - ); + return expectTransactionFailedWithoutReasonAsync(tokenRegWrapper.addTokenAsync(duplicateNameToken, owner)); }); it('should throw if symbol already exists', async () => { @@ -109,7 +107,7 @@ describe('TokenRegistry', () => { symbol: token1.symbol, }); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( tokenRegWrapper.addTokenAsync(duplicateSymbolToken, owner), ); }); @@ -136,7 +134,7 @@ describe('TokenRegistry', () => { describe('setTokenName', () => { it('should throw when not called by owner', async () => { - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( tokenReg.setTokenName.sendTransactionAsync(token1.address, token2.name, { from: notOwner }), ); }); @@ -162,13 +160,13 @@ describe('TokenRegistry', () => { it('should throw if the name already exists', async () => { await tokenRegWrapper.addTokenAsync(token2, owner); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( tokenReg.setTokenName.sendTransactionAsync(token1.address, token2.name, { from: owner }), ); }); it('should throw if token does not exist', async () => { - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( tokenReg.setTokenName.sendTransactionAsync(nullToken.address, token2.name, { from: owner }), ); }); @@ -176,7 +174,7 @@ describe('TokenRegistry', () => { describe('setTokenSymbol', () => { it('should throw when not called by owner', async () => { - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( tokenReg.setTokenSymbol.sendTransactionAsync(token1.address, token2.symbol, { from: notOwner, }), @@ -202,7 +200,7 @@ describe('TokenRegistry', () => { it('should throw if the symbol already exists', async () => { await tokenRegWrapper.addTokenAsync(token2, owner); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( tokenReg.setTokenSymbol.sendTransactionAsync(token1.address, token2.symbol, { from: owner, }), @@ -210,7 +208,7 @@ describe('TokenRegistry', () => { }); it('should throw if token does not exist', async () => { - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( tokenReg.setTokenSymbol.sendTransactionAsync(nullToken.address, token2.symbol, { from: owner, }), @@ -221,7 +219,7 @@ describe('TokenRegistry', () => { describe('removeToken', () => { it('should throw if not called by owner', async () => { const index = new BigNumber(0); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( tokenReg.removeToken.sendTransactionAsync(token1.address, index, { from: notOwner }), ); }); @@ -240,7 +238,7 @@ describe('TokenRegistry', () => { it('should throw if token does not exist', async () => { const index = new BigNumber(0); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( tokenReg.removeToken.sendTransactionAsync(nullToken.address, index, { from: owner }), ); }); @@ -248,7 +246,7 @@ describe('TokenRegistry', () => { it('should throw if token at given index does not match address', async () => { await tokenRegWrapper.addTokenAsync(token2, owner); const incorrectIndex = new BigNumber(0); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( tokenReg.removeToken.sendTransactionAsync(token2.address, incorrectIndex, { from: owner }), ); }); diff --git a/packages/contracts/test/tokens/ether_token.ts b/packages/contracts/test/tokens/ether_token.ts index 25ef15595..a104fc915 100644 --- a/packages/contracts/test/tokens/ether_token.ts +++ b/packages/contracts/test/tokens/ether_token.ts @@ -5,7 +5,7 @@ import * as chai from 'chai'; import { WETH9Contract } from '../../generated_contract_wrappers/weth9'; import { artifacts } from '../utils/artifacts'; -import { expectInsufficientFundsAsync, expectRevertOrAlwaysFailingTransactionAsync } from '../utils/assertions'; +import { expectInsufficientFundsAsync, expectTransactionFailedWithoutReasonAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper'; @@ -74,7 +74,7 @@ describe('EtherToken', () => { const initEthTokenBalance = await etherToken.balanceOf.callAsync(account); const ethTokensToWithdraw = initEthTokenBalance.plus(1); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectTransactionFailedWithoutReasonAsync( etherToken.withdraw.sendTransactionAsync(ethTokensToWithdraw), ); }); diff --git a/packages/contracts/test/tokens/unlimited_allowance_token.ts b/packages/contracts/test/tokens/unlimited_allowance_token.ts index 09a24950c..8a3b20d0f 100644 --- a/packages/contracts/test/tokens/unlimited_allowance_token.ts +++ b/packages/contracts/test/tokens/unlimited_allowance_token.ts @@ -5,7 +5,7 @@ import * as chai from 'chai'; import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token'; import { artifacts } from '../utils/artifacts'; -import { expectRevertOrOtherErrorAsync } from '../utils/assertions'; +import { expectContractCallFailed } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper'; @@ -54,7 +54,7 @@ describe('UnlimitedAllowanceToken', () => { it('should throw if owner has insufficient balance', async () => { const ownerBalance = await token.balanceOf.callAsync(owner); const amountToTransfer = ownerBalance.plus(1); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( token.transfer.callAsync(spender, amountToTransfer, { from: owner }), RevertReason.Erc20InsufficientBalance, ); @@ -93,7 +93,7 @@ describe('UnlimitedAllowanceToken', () => { await token.approve.sendTransactionAsync(spender, amountToTransfer, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( token.transferFrom.callAsync(owner, spender, amountToTransfer, { from: spender, }), @@ -109,7 +109,7 @@ describe('UnlimitedAllowanceToken', () => { const isSpenderAllowanceInsufficient = spenderAllowance.cmp(amountToTransfer) < 0; expect(isSpenderAllowanceInsufficient).to.be.true(); - return expectRevertOrOtherErrorAsync( + return expectContractCallFailed( token.transferFrom.callAsync(owner, spender, amountToTransfer, { from: spender, }), diff --git a/packages/contracts/test/utils/assertions.ts b/packages/contracts/test/utils/assertions.ts index baba892d3..89e90ad2f 100644 --- a/packages/contracts/test/utils/assertions.ts +++ b/packages/contracts/test/utils/assertions.ts @@ -1,108 +1,153 @@ import { RevertReason } from '@0xproject/types'; +import { logUtils } from '@0xproject/utils'; +import { NodeType } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import { TransactionReceipt, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; -import { constants } from './constants'; import { web3Wrapper } from './web3_wrapper'; const expect = chai.expect; -function _expectEitherErrorAsync(p: Promise, error1: string, error2: string): PromiseLike { - return expect(p) - .to.be.rejected() - .then(e => { - expect(e).to.satisfy( - (err: Error) => _.includes(err.message, error1) || _.includes(err.message, error2), - `expected promise to reject with error message that includes "${error1}" or "${error2}", but got: ` + - `"${e.message}"\n`, - ); - }); +// Represents the return value of a `sendTransaction` call. The Promise should +// resolve with either a transaction receipt or a transaction hash. +export type sendTransactionResult = Promise; + +async function _getGanacheOrGethError(ganacheError: string, gethError: string): Promise { + const nodeType = await web3Wrapper.getNodeTypeAsync(); + switch (nodeType) { + case NodeType.Ganache: + return ganacheError; + case NodeType.Geth: + return gethError; + default: + throw new Error(`Unknown node type: ${nodeType}`); + } +} + +async function _getInsufficientFundsErrorMessageAsync(): Promise { + return _getGanacheOrGethError("sender doesn't have enough funds", 'insufficient funds'); +} + +async function _getTransactionFailedErrorMessageAsync(): Promise { + return _getGanacheOrGethError('revert', 'always failing transaction'); +} + +async function _getContractCallFailedErrorMessageAsync(): Promise { + return _getGanacheOrGethError('revert', 'Contract call failed'); } /** * Rejects if the given Promise does not reject with an error indicating * insufficient funds. - * @param p the Promise which is expected to reject + * @param p a promise resulting from a contract call or sendTransaction call. * @returns a new Promise which will reject if the conditions are not met and * otherwise resolve with no value. */ -export function expectInsufficientFundsAsync(p: Promise): PromiseLike { - return _expectEitherErrorAsync(p, 'insufficient funds', "sender doesn't have enough funds"); +export async function expectInsufficientFundsAsync(p: Promise): Promise { + const errMessage = await _getInsufficientFundsErrorMessageAsync(); + return expect(p).to.be.rejectedWith(errMessage); } /** - * Rejects if the given Promise does not reject with a "revert" error or the - * given otherError. - * @param p the Promise which is expected to reject - * @param otherError the other error which is accepted as a valid reject error. + * Resolves if the the sendTransaction call fails with the given revert reason. + * However, since Geth does not support revert reasons for sendTransaction, this + * falls back to expectTransactionFailedWithoutReasonAsync if the backing + * Ethereum node is Geth. + * @param p a Promise resulting from a sendTransaction call + * @param reason a specific revert reason * @returns a new Promise which will reject if the conditions are not met and * otherwise resolve with no value. */ -export function expectRevertOrOtherErrorAsync(p: Promise, otherError: string): PromiseLike { - return _expectEitherErrorAsync(p, constants.REVERT, otherError); -} +export async function expectTransactionFailedAsync(p: sendTransactionResult, reason: RevertReason): Promise { + // HACK(albrow): This dummy `catch` should not be necessary, but if you + // remove it, there is an uncaught exception and the Node process will + // forcibly exit. It's possible this is a false positive in + // make-promises-safe. + p.catch(e => { + _.noop(e); + }); -/** - * Rejects if the given Promise does not reject with a "revert" or "always - * failing transaction" error. - * @param p the Promise which is expected to reject - * @returns a new Promise which will reject if the conditions are not met and - * otherwise resolve with no value. - */ -export function expectRevertOrAlwaysFailingTransactionAsync(p: Promise): PromiseLike { - return expectRevertOrOtherErrorAsync(p, 'always failing transaction'); + const nodeType = await web3Wrapper.getNodeTypeAsync(); + switch (nodeType) { + case NodeType.Ganache: + return expect(p).to.be.rejectedWith(reason); + case NodeType.Geth: + logUtils.warn( + 'WARNING: Geth does not support revert reasons for sendTransaction. This test will pass if the transaction fails for any reason.', + ); + return expectTransactionFailedWithoutReasonAsync(p); + default: + throw new Error(`Unknown node type: ${nodeType}`); + } } /** - * Rejects if at least one the following conditions is not met: - * 1) The given Promise rejects with the given revert reason. - * 2) The given Promise rejects with an error containing "always failing transaction" - * 3) The given Promise fulfills with a txReceipt that has a status of 0 or '0', indicating the transaction failed. - * 4) The given Promise fulfills with a txHash and corresponding txReceipt has a status of 0 or '0'. - * @param p the Promise which is expected to reject - * @param reason a specific revert reason + * Resolves if the transaction fails without a revert reason, or if the + * corresponding transactionReceipt has a status of 0 or '0', indicating + * failure. + * @param p a Promise resulting from a sendTransaction call * @returns a new Promise which will reject if the conditions are not met and * otherwise resolve with no value. */ -export async function expectRevertReasonOrAlwaysFailingTransactionAsync( - p: Promise, - reason: RevertReason, -): Promise { +export async function expectTransactionFailedWithoutReasonAsync(p: sendTransactionResult): Promise { return p .then(async result => { - let txReceiptStatus: string | 0 | 1 | null; - if (typeof result === 'string') { - // Result is a txHash. We need to make a web3 call to get the receipt. + let txReceiptStatus: null | string | 0 | 1; + if (_.isString(result)) { + // Result is a txHash. We need to make a web3 call to get the + // receipt, then get the status from the receipt. const txReceipt = await web3Wrapper.awaitTransactionMinedAsync(result); txReceiptStatus = txReceipt.status; } else if ('status' in result) { - // Result is a TransactionReceiptWithDecodedLogs or TransactionReceipt - // and status is a field of result. + // Result is a transaction receipt, so we can get the status + // directly. txReceiptStatus = result.status; } else { - throw new Error('Unexpected result type'); + throw new Error('Unexpected result type: ' + typeof result); } expect(_.toString(txReceiptStatus)).to.equal( '0', - 'transactionReceipt had a non-zero status, indicating success', + 'Expected transaction to fail but receipt had a non-zero status, indicating success', ); }) - .catch(err => { - expect(err.message).to.satisfy( - (msg: string) => _.includes(msg, reason) || _.includes(msg, 'always failing transaction'), - `Expected ${reason} or 'always failing transaction' but error message was ${err.message}`, - ); + .catch(async err => { + // If the promise rejects, we expect a specific error message, + // depending on the backing Ethereum node type. + const errMessage = await _getTransactionFailedErrorMessageAsync(); + expect(err.message).to.include(errMessage); }); } /** - * Rejects if the given Promise does not reject with a "revert" or "Contract - * call failed" error. - * @param p the Promise which is expected to reject + * Resolves if the the contract call fails with the given revert reason. + * @param p a Promise resulting from a contract call + * @param reason a specific revert reason + * @returns a new Promise which will reject if the conditions are not met and + * otherwise resolve with no value. + */ +export async function expectContractCallFailed(p: Promise, reason: RevertReason): Promise { + return expect(p).to.be.rejectedWith(reason); +} + +/** + * Resolves if the contract call fails without a revert reason. + * @param p a Promise resulting from a contract call + * @returns a new Promise which will reject if the conditions are not met and + * otherwise resolve with no value. + */ +export async function expectContractCallFailedWithoutReasonAsync(p: Promise): Promise { + const errMessage = await _getContractCallFailedErrorMessageAsync(); + return expect(p).to.be.rejectedWith(errMessage); +} + +/** + * Resolves if the contract creation/deployment fails without a revert reason. + * @param p a Promise resulting from a contract creation/deployment * @returns a new Promise which will reject if the conditions are not met and * otherwise resolve with no value. */ -export function expectRevertOrContractCallFailedAsync(p: Promise): PromiseLike { - return expectRevertOrOtherErrorAsync(p, 'Contract call failed'); +export async function expectContractCreationFailedWithoutReason(p: Promise): Promise { + const errMessage = await _getTransactionFailedErrorMessageAsync(); + return expect(p).to.be.rejectedWith(errMessage); } diff --git a/packages/contracts/test/utils/constants.ts b/packages/contracts/test/utils/constants.ts index 8e68f376d..7f3ad62e1 100644 --- a/packages/contracts/test/utils/constants.ts +++ b/packages/contracts/test/utils/constants.ts @@ -18,7 +18,6 @@ const TESTRPC_PRIVATE_KEYS_STRINGS = [ export const constants = { INVALID_OPCODE: 'invalid opcode', - REVERT: 'revert', TESTRPC_NETWORK_ID: 50, // Note(albrow): In practice V8 and most other engines limit the minimum // interval for setInterval to 10ms. We still set it to 0 here in order to diff --git a/packages/contracts/test/utils/core_combinatorial_utils.ts b/packages/contracts/test/utils/core_combinatorial_utils.ts index 38723d53d..8c6c83014 100644 --- a/packages/contracts/test/utils/core_combinatorial_utils.ts +++ b/packages/contracts/test/utils/core_combinatorial_utils.ts @@ -17,7 +17,7 @@ import 'make-promises-safe'; import { ExchangeContract, FillContractEventArgs } from '../../generated_contract_wrappers/exchange'; import { artifacts } from './artifacts'; -import { expectRevertReasonOrAlwaysFailingTransactionAsync } from './assertions'; +import { expectTransactionFailedAsync } from './assertions'; import { AssetWrapper } from './asset_wrapper'; import { chaiSetup } from './chai_setup'; import { constants } from './constants'; @@ -418,7 +418,7 @@ export class CoreCombinatorialUtils { fillRevertReasonIfExists: RevertReason | undefined, ): Promise { if (!_.isUndefined(fillRevertReasonIfExists)) { - return expectRevertReasonOrAlwaysFailingTransactionAsync( + return expectTransactionFailedAsync( this.exchangeWrapper.fillOrderAsync(signedOrder, this.takerAddress, { takerAssetFillAmount }), fillRevertReasonIfExists, ); diff --git a/packages/dev-utils/src/blockchain_lifecycle.ts b/packages/dev-utils/src/blockchain_lifecycle.ts index 587332f1a..abca6d386 100644 --- a/packages/dev-utils/src/blockchain_lifecycle.ts +++ b/packages/dev-utils/src/blockchain_lifecycle.ts @@ -1,11 +1,5 @@ import { logUtils } from '@0xproject/utils'; -import { uniqueVersionIds, Web3Wrapper } from '@0xproject/web3-wrapper'; -import { includes } from 'lodash'; - -enum NodeType { - Geth = 'GETH', - Ganache = 'GANACHE', -} +import { NodeType, Web3Wrapper } from '@0xproject/web3-wrapper'; // HACK(albrow): 🐉 We have to do this so that debug.setHead works correctly. // (Geth does not seem to like debug.setHead(0), so by sending some transactions @@ -23,7 +17,7 @@ export class BlockchainLifecycle { this._snapshotIdsStack = []; } public async startAsync(): Promise { - const nodeType = await this._getNodeTypeAsync(); + const nodeType = await this._web3Wrapper.getNodeTypeAsync(); switch (nodeType) { case NodeType.Ganache: const snapshotId = await this._web3Wrapper.takeSnapshotAsync(); @@ -44,7 +38,7 @@ export class BlockchainLifecycle { } } public async revertAsync(): Promise { - const nodeType = await this._getNodeTypeAsync(); + const nodeType = await this._web3Wrapper.getNodeTypeAsync(); switch (nodeType) { case NodeType.Ganache: const snapshotId = this._snapshotIdsStack.pop() as number; @@ -61,16 +55,6 @@ export class BlockchainLifecycle { throw new Error(`Unknown node type: ${nodeType}`); } } - private async _getNodeTypeAsync(): Promise { - const version = await this._web3Wrapper.getNodeVersionAsync(); - if (includes(version, uniqueVersionIds.geth)) { - return NodeType.Geth; - } else if (includes(version, uniqueVersionIds.ganache)) { - return NodeType.Ganache; - } else { - throw new Error(`Unknown client version: ${version}`); - } - } private async _mineMinimumBlocksAsync(): Promise { logUtils.warn('WARNING: minimum block number for tests not met. Mining additional blocks...'); if (this._addresses.length === 0) { diff --git a/packages/migrations/artifacts/2.0.0/ZRXToken.json b/packages/migrations/artifacts/2.0.0/ZRXToken.json index cad596044..2078bb4d6 100644 --- a/packages/migrations/artifacts/2.0.0/ZRXToken.json +++ b/packages/migrations/artifacts/2.0.0/ZRXToken.json @@ -228,39 +228,39 @@ "evm": { "bytecode": { "linkReferences": {}, - "object": "0x60806040526b033b2e3c9fd0803ce800000060035534801561002057600080fd5b506003543360009081526020819052604090205561067b806100436000396000f3006080604052600436106100985763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461009d578063095ea7b31461012757806318160ddd1461016c57806323b872dd14610193578063313ce567146101ca57806370a08231146101f557806395d89b4114610223578063a9059cbb14610238578063dd62ed3e14610269575b600080fd5b3480156100a957600080fd5b506100b261029d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100ec5781810151838201526020016100d4565b50505050905090810190601f1680156101195780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561013357600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff600435166024356102d4565b604080519115158252519081900360200190f35b34801561017857600080fd5b50610181610348565b60408051918252519081900360200190f35b34801561019f57600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff6004358116906024351660443561034e565b3480156101d657600080fd5b506101df6104e8565b6040805160ff9092168252519081900360200190f35b34801561020157600080fd5b5061018173ffffffffffffffffffffffffffffffffffffffff600435166104ed565b34801561022f57600080fd5b506100b2610515565b34801561024457600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff6004351660243561054c565b34801561027557600080fd5b5061018173ffffffffffffffffffffffffffffffffffffffff60043581169060243516610617565b60408051808201909152601181527f30782050726f746f636f6c20546f6b656e000000000000000000000000000000602082015281565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60035481565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260016020908152604080832033845282528083205493835290829052812054909190831180159061039b5750828110155b80156103ce575073ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205483810110155b156104db5773ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220805487019055918716815220805484900390557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81101561046d5773ffffffffffffffffffffffffffffffffffffffff851660009081526001602090815260408083203384529091529020805484900390555b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191506104e0565b600091505b509392505050565b601281565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b60408051808201909152600381527f5a52580000000000000000000000000000000000000000000000000000000000602082015281565b336000908152602081905260408120548211801590610592575073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110155b1561060f57336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3506001610342565b506000610342565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600160209081526040808320939094168252919091522054905600a165627a7a72305820a64d50ba7ca8023b64d00c49e38afa498258fdc2e4a694ef1c57201e9a757ec10029", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH12 0x33B2E3C9FD0803CE8000000 PUSH1 0x3 SSTORE CALLVALUE DUP1 ISZERO PUSH2 0x20 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x3 SLOAD CALLER PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SSTORE PUSH2 0x67B DUP1 PUSH2 0x43 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x98 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x6FDDE03 DUP2 EQ PUSH2 0x9D JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x127 JUMPI DUP1 PUSH4 0x18160DDD EQ PUSH2 0x16C JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x193 JUMPI DUP1 PUSH4 0x313CE567 EQ PUSH2 0x1CA JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x1F5 JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x223 JUMPI DUP1 PUSH4 0xA9059CBB EQ PUSH2 0x238 JUMPI DUP1 PUSH4 0xDD62ED3E EQ PUSH2 0x269 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xA9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x29D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP1 DUP3 MSTORE DUP4 MLOAD DUP2 DUP4 ADD MSTORE DUP4 MLOAD SWAP2 SWAP3 DUP4 SWAP3 SWAP1 DUP4 ADD SWAP2 DUP6 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xEC JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0xD4 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x119 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x133 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD PUSH2 0x2D4 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x178 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH2 0x348 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x19F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH1 0x44 CALLDATALOAD PUSH2 0x34E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1DF PUSH2 0x4E8 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0xFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x201 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x4ED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x22F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x515 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x244 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD PUSH2 0x54C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x275 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH2 0x617 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x11 DUP2 MSTORE PUSH32 0x30782050726F746F636F6C20546F6B656E000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND DUP1 DUP6 MSTORE SWAP1 DUP4 MSTORE DUP2 DUP5 KECCAK256 DUP7 SWAP1 SSTORE DUP2 MLOAD DUP7 DUP2 MSTORE SWAP2 MLOAD SWAP4 SWAP5 SWAP1 SWAP4 SWAP1 SWAP3 PUSH32 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925 SWAP3 DUP3 SWAP1 SUB ADD SWAP1 LOG3 POP PUSH1 0x1 JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x3 SLOAD DUP2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP5 MSTORE DUP3 MSTORE DUP1 DUP4 KECCAK256 SLOAD SWAP4 DUP4 MSTORE SWAP1 DUP3 SWAP1 MSTORE DUP2 KECCAK256 SLOAD SWAP1 SWAP2 SWAP1 DUP4 GT DUP1 ISZERO SWAP1 PUSH2 0x39B JUMPI POP DUP3 DUP2 LT ISZERO JUMPDEST DUP1 ISZERO PUSH2 0x3CE JUMPI POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 DUP2 ADD LT ISZERO JUMPDEST ISZERO PUSH2 0x4DB JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP6 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD DUP8 ADD SWAP1 SSTORE SWAP2 DUP8 AND DUP2 MSTORE KECCAK256 DUP1 SLOAD DUP5 SWAP1 SUB SWAP1 SSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 LT ISZERO PUSH2 0x46D JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP5 MSTORE SWAP1 SWAP2 MSTORE SWAP1 KECCAK256 DUP1 SLOAD DUP5 SWAP1 SUB SWAP1 SSTORE JUMPDEST DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF DUP6 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH1 0x1 SWAP2 POP PUSH2 0x4E0 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x12 DUP2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x3 DUP2 MSTORE PUSH32 0x5A52580000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST CALLER PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 SLOAD DUP3 GT DUP1 ISZERO SWAP1 PUSH2 0x592 JUMPI POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 DUP2 ADD LT ISZERO JUMPDEST ISZERO PUSH2 0x60F JUMPI CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD DUP8 SWAP1 SUB SWAP1 SSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND DUP1 DUP5 MSTORE SWAP3 DUP2 SWAP1 KECCAK256 DUP1 SLOAD DUP8 ADD SWAP1 SSTORE DUP1 MLOAD DUP7 DUP2 MSTORE SWAP1 MLOAD SWAP3 SWAP4 SWAP3 PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF SWAP3 SWAP2 DUP2 SWAP1 SUB SWAP1 SWAP2 ADD SWAP1 LOG3 POP PUSH1 0x1 PUSH2 0x342 JUMP JUMPDEST POP PUSH1 0x0 PUSH2 0x342 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 SWAP1 SWAP5 AND DUP3 MSTORE SWAP2 SWAP1 SWAP2 MSTORE KECCAK256 SLOAD SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xa6 0x4d POP 0xba PUSH29 0xA8023B64D00C49E38AFA498258FDC2E4A694EF1C57201E9A757EC10029 ", - "sourceMap": "753:342:0:-;;;872:6;846:32;;1022:71;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1075:11:0;;1061:10;1052:8;:20;;;;;;;;;;:34;753:342;;;;;;" + "object": "0x60806040526b033b2e3c9fd0803ce800000060035534801561002057600080fd5b506003543360009081526020819052604090205561067b806100436000396000f3006080604052600436106100985763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461009d578063095ea7b31461012757806318160ddd1461016c57806323b872dd14610193578063313ce567146101ca57806370a08231146101f557806395d89b4114610223578063a9059cbb14610238578063dd62ed3e14610269575b600080fd5b3480156100a957600080fd5b506100b261029d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100ec5781810151838201526020016100d4565b50505050905090810190601f1680156101195780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561013357600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff600435166024356102d4565b604080519115158252519081900360200190f35b34801561017857600080fd5b50610181610348565b60408051918252519081900360200190f35b34801561019f57600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff6004358116906024351660443561034e565b3480156101d657600080fd5b506101df6104e8565b6040805160ff9092168252519081900360200190f35b34801561020157600080fd5b5061018173ffffffffffffffffffffffffffffffffffffffff600435166104ed565b34801561022f57600080fd5b506100b2610515565b34801561024457600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff6004351660243561054c565b34801561027557600080fd5b5061018173ffffffffffffffffffffffffffffffffffffffff60043581169060243516610617565b60408051808201909152601181527f30782050726f746f636f6c20546f6b656e000000000000000000000000000000602082015281565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60035481565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260016020908152604080832033845282528083205493835290829052812054909190831180159061039b5750828110155b80156103ce575073ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205483810110155b156104db5773ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220805487019055918716815220805484900390557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81101561046d5773ffffffffffffffffffffffffffffffffffffffff851660009081526001602090815260408083203384529091529020805484900390555b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191506104e0565b600091505b509392505050565b601281565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b60408051808201909152600381527f5a52580000000000000000000000000000000000000000000000000000000000602082015281565b336000908152602081905260408120548211801590610592575073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110155b1561060f57336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3506001610342565b506000610342565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600160209081526040808320939094168252919091522054905600a165627a7a72305820d9d363d7eef4f71b2db22174233e9d08dc044f8bfd3ec76c93b896b38fefdf0b0029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH12 0x33B2E3C9FD0803CE8000000 PUSH1 0x3 SSTORE CALLVALUE DUP1 ISZERO PUSH2 0x20 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x3 SLOAD CALLER PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SSTORE PUSH2 0x67B DUP1 PUSH2 0x43 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x98 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x6FDDE03 DUP2 EQ PUSH2 0x9D JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x127 JUMPI DUP1 PUSH4 0x18160DDD EQ PUSH2 0x16C JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x193 JUMPI DUP1 PUSH4 0x313CE567 EQ PUSH2 0x1CA JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x1F5 JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x223 JUMPI DUP1 PUSH4 0xA9059CBB EQ PUSH2 0x238 JUMPI DUP1 PUSH4 0xDD62ED3E EQ PUSH2 0x269 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xA9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x29D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP1 DUP3 MSTORE DUP4 MLOAD DUP2 DUP4 ADD MSTORE DUP4 MLOAD SWAP2 SWAP3 DUP4 SWAP3 SWAP1 DUP4 ADD SWAP2 DUP6 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xEC JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0xD4 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x119 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x133 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD PUSH2 0x2D4 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x178 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH2 0x348 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x19F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH1 0x44 CALLDATALOAD PUSH2 0x34E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1DF PUSH2 0x4E8 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0xFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x201 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x4ED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x22F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x515 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x244 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD PUSH2 0x54C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x275 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH2 0x617 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x11 DUP2 MSTORE PUSH32 0x30782050726F746F636F6C20546F6B656E000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND DUP1 DUP6 MSTORE SWAP1 DUP4 MSTORE DUP2 DUP5 KECCAK256 DUP7 SWAP1 SSTORE DUP2 MLOAD DUP7 DUP2 MSTORE SWAP2 MLOAD SWAP4 SWAP5 SWAP1 SWAP4 SWAP1 SWAP3 PUSH32 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925 SWAP3 DUP3 SWAP1 SUB ADD SWAP1 LOG3 POP PUSH1 0x1 JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x3 SLOAD DUP2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP5 MSTORE DUP3 MSTORE DUP1 DUP4 KECCAK256 SLOAD SWAP4 DUP4 MSTORE SWAP1 DUP3 SWAP1 MSTORE DUP2 KECCAK256 SLOAD SWAP1 SWAP2 SWAP1 DUP4 GT DUP1 ISZERO SWAP1 PUSH2 0x39B JUMPI POP DUP3 DUP2 LT ISZERO JUMPDEST DUP1 ISZERO PUSH2 0x3CE JUMPI POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 DUP2 ADD LT ISZERO JUMPDEST ISZERO PUSH2 0x4DB JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP6 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD DUP8 ADD SWAP1 SSTORE SWAP2 DUP8 AND DUP2 MSTORE KECCAK256 DUP1 SLOAD DUP5 SWAP1 SUB SWAP1 SSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 LT ISZERO PUSH2 0x46D JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP5 MSTORE SWAP1 SWAP2 MSTORE SWAP1 KECCAK256 DUP1 SLOAD DUP5 SWAP1 SUB SWAP1 SSTORE JUMPDEST DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF DUP6 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH1 0x1 SWAP2 POP PUSH2 0x4E0 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x12 DUP2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x3 DUP2 MSTORE PUSH32 0x5A52580000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST CALLER PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 SLOAD DUP3 GT DUP1 ISZERO SWAP1 PUSH2 0x592 JUMPI POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 DUP2 ADD LT ISZERO JUMPDEST ISZERO PUSH2 0x60F JUMPI CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD DUP8 SWAP1 SUB SWAP1 SSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND DUP1 DUP5 MSTORE SWAP3 DUP2 SWAP1 KECCAK256 DUP1 SLOAD DUP8 ADD SWAP1 SSTORE DUP1 MLOAD DUP7 DUP2 MSTORE SWAP1 MLOAD SWAP3 SWAP4 SWAP3 PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF SWAP3 SWAP2 DUP2 SWAP1 SUB SWAP1 SWAP2 ADD SWAP1 LOG3 POP PUSH1 0x1 PUSH2 0x342 JUMP JUMPDEST POP PUSH1 0x0 PUSH2 0x342 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 SWAP1 SWAP5 AND DUP3 MSTORE SWAP2 SWAP1 SWAP2 MSTORE KECCAK256 SLOAD SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd9 0xd3 PUSH4 0xD7EEF4F7 SHL 0x2d 0xb2 0x21 PUSH21 0x233E9D08DC044F8BFD3EC76C93B896B38FEFDF0B00 0x29 ", + "sourceMap": "750:342:3:-;;;869:6;843:32;;1019:71;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1072:11:3;;1058:10;1049:8;:20;;;;;;;;;;:34;750:342;;;;;;" }, "deployedBytecode": { "linkReferences": {}, - "object": "0x6080604052600436106100985763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461009d578063095ea7b31461012757806318160ddd1461016c57806323b872dd14610193578063313ce567146101ca57806370a08231146101f557806395d89b4114610223578063a9059cbb14610238578063dd62ed3e14610269575b600080fd5b3480156100a957600080fd5b506100b261029d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100ec5781810151838201526020016100d4565b50505050905090810190601f1680156101195780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561013357600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff600435166024356102d4565b604080519115158252519081900360200190f35b34801561017857600080fd5b50610181610348565b60408051918252519081900360200190f35b34801561019f57600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff6004358116906024351660443561034e565b3480156101d657600080fd5b506101df6104e8565b6040805160ff9092168252519081900360200190f35b34801561020157600080fd5b5061018173ffffffffffffffffffffffffffffffffffffffff600435166104ed565b34801561022f57600080fd5b506100b2610515565b34801561024457600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff6004351660243561054c565b34801561027557600080fd5b5061018173ffffffffffffffffffffffffffffffffffffffff60043581169060243516610617565b60408051808201909152601181527f30782050726f746f636f6c20546f6b656e000000000000000000000000000000602082015281565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60035481565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260016020908152604080832033845282528083205493835290829052812054909190831180159061039b5750828110155b80156103ce575073ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205483810110155b156104db5773ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220805487019055918716815220805484900390557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81101561046d5773ffffffffffffffffffffffffffffffffffffffff851660009081526001602090815260408083203384529091529020805484900390555b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191506104e0565b600091505b509392505050565b601281565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b60408051808201909152600381527f5a52580000000000000000000000000000000000000000000000000000000000602082015281565b336000908152602081905260408120548211801590610592575073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110155b1561060f57336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3506001610342565b506000610342565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600160209081526040808320939094168252919091522054905600a165627a7a72305820a64d50ba7ca8023b64d00c49e38afa498258fdc2e4a694ef1c57201e9a757ec10029", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x98 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x6FDDE03 DUP2 EQ PUSH2 0x9D JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x127 JUMPI DUP1 PUSH4 0x18160DDD EQ PUSH2 0x16C JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x193 JUMPI DUP1 PUSH4 0x313CE567 EQ PUSH2 0x1CA JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x1F5 JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x223 JUMPI DUP1 PUSH4 0xA9059CBB EQ PUSH2 0x238 JUMPI DUP1 PUSH4 0xDD62ED3E EQ PUSH2 0x269 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xA9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x29D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP1 DUP3 MSTORE DUP4 MLOAD DUP2 DUP4 ADD MSTORE DUP4 MLOAD SWAP2 SWAP3 DUP4 SWAP3 SWAP1 DUP4 ADD SWAP2 DUP6 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xEC JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0xD4 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x119 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x133 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD PUSH2 0x2D4 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x178 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH2 0x348 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x19F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH1 0x44 CALLDATALOAD PUSH2 0x34E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1DF PUSH2 0x4E8 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0xFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x201 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x4ED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x22F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x515 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x244 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD PUSH2 0x54C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x275 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH2 0x617 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x11 DUP2 MSTORE PUSH32 0x30782050726F746F636F6C20546F6B656E000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND DUP1 DUP6 MSTORE SWAP1 DUP4 MSTORE DUP2 DUP5 KECCAK256 DUP7 SWAP1 SSTORE DUP2 MLOAD DUP7 DUP2 MSTORE SWAP2 MLOAD SWAP4 SWAP5 SWAP1 SWAP4 SWAP1 SWAP3 PUSH32 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925 SWAP3 DUP3 SWAP1 SUB ADD SWAP1 LOG3 POP PUSH1 0x1 JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x3 SLOAD DUP2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP5 MSTORE DUP3 MSTORE DUP1 DUP4 KECCAK256 SLOAD SWAP4 DUP4 MSTORE SWAP1 DUP3 SWAP1 MSTORE DUP2 KECCAK256 SLOAD SWAP1 SWAP2 SWAP1 DUP4 GT DUP1 ISZERO SWAP1 PUSH2 0x39B JUMPI POP DUP3 DUP2 LT ISZERO JUMPDEST DUP1 ISZERO PUSH2 0x3CE JUMPI POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 DUP2 ADD LT ISZERO JUMPDEST ISZERO PUSH2 0x4DB JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP6 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD DUP8 ADD SWAP1 SSTORE SWAP2 DUP8 AND DUP2 MSTORE KECCAK256 DUP1 SLOAD DUP5 SWAP1 SUB SWAP1 SSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 LT ISZERO PUSH2 0x46D JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP5 MSTORE SWAP1 SWAP2 MSTORE SWAP1 KECCAK256 DUP1 SLOAD DUP5 SWAP1 SUB SWAP1 SSTORE JUMPDEST DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF DUP6 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH1 0x1 SWAP2 POP PUSH2 0x4E0 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x12 DUP2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x3 DUP2 MSTORE PUSH32 0x5A52580000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST CALLER PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 SLOAD DUP3 GT DUP1 ISZERO SWAP1 PUSH2 0x592 JUMPI POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 DUP2 ADD LT ISZERO JUMPDEST ISZERO PUSH2 0x60F JUMPI CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD DUP8 SWAP1 SUB SWAP1 SSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND DUP1 DUP5 MSTORE SWAP3 DUP2 SWAP1 KECCAK256 DUP1 SLOAD DUP8 ADD SWAP1 SSTORE DUP1 MLOAD DUP7 DUP2 MSTORE SWAP1 MLOAD SWAP3 SWAP4 SWAP3 PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF SWAP3 SWAP2 DUP2 SWAP1 SUB SWAP1 SWAP2 ADD SWAP1 LOG3 POP PUSH1 0x1 PUSH2 0x342 JUMP JUMPDEST POP PUSH1 0x0 PUSH2 0x342 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 SWAP1 SWAP5 AND DUP3 MSTORE SWAP2 SWAP1 SWAP2 MSTORE KECCAK256 SLOAD SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xa6 0x4d POP 0xba PUSH29 0xA8023B64D00C49E38AFA498258FDC2E4A694EF1C57201E9A757EC10029 ", - "sourceMap": "753:342:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;923:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;923:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;923:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1087:187:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1087:187:1;;;;;;;;;;;;;;;;;;;;;;;;;;;846:32:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;846:32:0;;;;;;;;;;;;;;;;;;;;1066:609:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1066:609:3;;;;;;;;;;;;;;805:35:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;805:35:0;;;;;;;;;;;;;;;;;;;;;;;982:99:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;982:99:1;;;;;;;978:37:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;978:37:0;;;;125:410:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;125:410:1;;;;;;;;;1280:126;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1280:126:1;;;;;;;;;;;;923:49:0;;;;;;;;;;;;;;;;;;;:::o;1087:187:1:-;1168:10;1144:4;1160:19;;;:7;:19;;;;;;;;;:29;;;;;;;;;;;:38;;;1208;;;;;;;1144:4;;1160:29;;1168:10;;1208:38;;;;;;;;-1:-1:-1;1263:4:1;1087:187;;;;;:::o;846:32:0:-;;;;:::o;1066:609:3:-;1198:14;;;1161:4;1198:14;;;:7;:14;;;;;;;;1213:10;1198:26;;;;;;;;1238:15;;;;;;;;;;1161:4;;1198:26;1238:25;-1:-1:-1;1238:25:3;;;:60;;;1292:6;1279:9;:19;;1238:60;:115;;;;-1:-1:-1;1340:13:3;;;:8;:13;;;;;;;;;;;1314:22;;;:39;;1238:115;1234:435;;;1378:13;;;;:8;:13;;;;;;;;;;;:23;;;;;;1415:15;;;;;;:25;;;;;;;768:10;1458:20;;1454:95;;;1498:14;;;;;;;:7;:14;;;;;;;;1513:10;1498:26;;;;;;;:36;;;;;;;1454:95;1578:3;1562:28;;1571:5;1562:28;;;1583:6;1562:28;;;;;;;;;;;;;;;;;;1611:4;1604:11;;;;1234:435;1653:5;1646:12;;1234:435;1066:609;;;;;;:::o;805:35:0:-;838:2;805:35;:::o;982:99:1:-;1058:16;;1035:4;1058:16;;;;;;;;;;;;982:99::o;978:37:0:-;;;;;;;;;;;;;;;;;;;:::o;125:410:1:-;276:10;178:4;267:20;;;;;;;;;;;:30;-1:-1:-1;267:30:1;;;:73;;-1:-1:-1;327:13:1;;;:8;:13;;;;;;;;;;;301:22;;;:39;;267:73;263:266;;;365:10;356:8;:20;;;;;;;;;;;:30;;;;;;;:20;400:13;;;;;;;;;:23;;;;;;437:33;;;;;;;400:13;;365:10;437:33;;;;;;;;;;;-1:-1:-1;491:4:1;484:11;;263:266;-1:-1:-1;521:5:1;514:12;;1280:126;1374:15;;;;1351:4;1374:15;;;:7;:15;;;;;;;;:25;;;;;;;;;;;;;1280:126::o" + "object": "0x6080604052600436106100985763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461009d578063095ea7b31461012757806318160ddd1461016c57806323b872dd14610193578063313ce567146101ca57806370a08231146101f557806395d89b4114610223578063a9059cbb14610238578063dd62ed3e14610269575b600080fd5b3480156100a957600080fd5b506100b261029d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100ec5781810151838201526020016100d4565b50505050905090810190601f1680156101195780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561013357600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff600435166024356102d4565b604080519115158252519081900360200190f35b34801561017857600080fd5b50610181610348565b60408051918252519081900360200190f35b34801561019f57600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff6004358116906024351660443561034e565b3480156101d657600080fd5b506101df6104e8565b6040805160ff9092168252519081900360200190f35b34801561020157600080fd5b5061018173ffffffffffffffffffffffffffffffffffffffff600435166104ed565b34801561022f57600080fd5b506100b2610515565b34801561024457600080fd5b5061015873ffffffffffffffffffffffffffffffffffffffff6004351660243561054c565b34801561027557600080fd5b5061018173ffffffffffffffffffffffffffffffffffffffff60043581169060243516610617565b60408051808201909152601181527f30782050726f746f636f6c20546f6b656e000000000000000000000000000000602082015281565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60035481565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260016020908152604080832033845282528083205493835290829052812054909190831180159061039b5750828110155b80156103ce575073ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205483810110155b156104db5773ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220805487019055918716815220805484900390557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81101561046d5773ffffffffffffffffffffffffffffffffffffffff851660009081526001602090815260408083203384529091529020805484900390555b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191506104e0565b600091505b509392505050565b601281565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b60408051808201909152600381527f5a52580000000000000000000000000000000000000000000000000000000000602082015281565b336000908152602081905260408120548211801590610592575073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110155b1561060f57336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3506001610342565b506000610342565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600160209081526040808320939094168252919091522054905600a165627a7a72305820d9d363d7eef4f71b2db22174233e9d08dc044f8bfd3ec76c93b896b38fefdf0b0029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x98 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x6FDDE03 DUP2 EQ PUSH2 0x9D JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x127 JUMPI DUP1 PUSH4 0x18160DDD EQ PUSH2 0x16C JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x193 JUMPI DUP1 PUSH4 0x313CE567 EQ PUSH2 0x1CA JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x1F5 JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x223 JUMPI DUP1 PUSH4 0xA9059CBB EQ PUSH2 0x238 JUMPI DUP1 PUSH4 0xDD62ED3E EQ PUSH2 0x269 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xA9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x29D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP1 DUP3 MSTORE DUP4 MLOAD DUP2 DUP4 ADD MSTORE DUP4 MLOAD SWAP2 SWAP3 DUP4 SWAP3 SWAP1 DUP4 ADD SWAP2 DUP6 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xEC JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0xD4 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x119 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x133 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD PUSH2 0x2D4 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x178 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH2 0x348 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x19F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH1 0x44 CALLDATALOAD PUSH2 0x34E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1DF PUSH2 0x4E8 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0xFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x201 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x4ED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x22F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x515 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x244 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD PUSH2 0x54C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x275 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH2 0x617 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x11 DUP2 MSTORE PUSH32 0x30782050726F746F636F6C20546F6B656E000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND DUP1 DUP6 MSTORE SWAP1 DUP4 MSTORE DUP2 DUP5 KECCAK256 DUP7 SWAP1 SSTORE DUP2 MLOAD DUP7 DUP2 MSTORE SWAP2 MLOAD SWAP4 SWAP5 SWAP1 SWAP4 SWAP1 SWAP3 PUSH32 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925 SWAP3 DUP3 SWAP1 SUB ADD SWAP1 LOG3 POP PUSH1 0x1 JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x3 SLOAD DUP2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP5 MSTORE DUP3 MSTORE DUP1 DUP4 KECCAK256 SLOAD SWAP4 DUP4 MSTORE SWAP1 DUP3 SWAP1 MSTORE DUP2 KECCAK256 SLOAD SWAP1 SWAP2 SWAP1 DUP4 GT DUP1 ISZERO SWAP1 PUSH2 0x39B JUMPI POP DUP3 DUP2 LT ISZERO JUMPDEST DUP1 ISZERO PUSH2 0x3CE JUMPI POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 DUP2 ADD LT ISZERO JUMPDEST ISZERO PUSH2 0x4DB JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP6 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD DUP8 ADD SWAP1 SSTORE SWAP2 DUP8 AND DUP2 MSTORE KECCAK256 DUP1 SLOAD DUP5 SWAP1 SUB SWAP1 SSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 LT ISZERO PUSH2 0x46D JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP5 MSTORE SWAP1 SWAP2 MSTORE SWAP1 KECCAK256 DUP1 SLOAD DUP5 SWAP1 SUB SWAP1 SSTORE JUMPDEST DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF DUP6 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH1 0x1 SWAP2 POP PUSH2 0x4E0 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x12 DUP2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x3 DUP2 MSTORE PUSH32 0x5A52580000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST CALLER PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 SLOAD DUP3 GT DUP1 ISZERO SWAP1 PUSH2 0x592 JUMPI POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 DUP2 ADD LT ISZERO JUMPDEST ISZERO PUSH2 0x60F JUMPI CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD DUP8 SWAP1 SUB SWAP1 SSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND DUP1 DUP5 MSTORE SWAP3 DUP2 SWAP1 KECCAK256 DUP1 SLOAD DUP8 ADD SWAP1 SSTORE DUP1 MLOAD DUP7 DUP2 MSTORE SWAP1 MLOAD SWAP3 SWAP4 SWAP3 PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF SWAP3 SWAP2 DUP2 SWAP1 SUB SWAP1 SWAP2 ADD SWAP1 LOG3 POP PUSH1 0x1 PUSH2 0x342 JUMP JUMPDEST POP PUSH1 0x0 PUSH2 0x342 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 SWAP1 SWAP5 AND DUP3 MSTORE SWAP2 SWAP1 SWAP2 MSTORE KECCAK256 SLOAD SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd9 0xd3 PUSH4 0xD7EEF4F7 SHL 0x2d 0xb2 0x21 PUSH21 0x233E9D08DC044F8BFD3EC76C93B896B38FEFDF0B00 0x29 ", + "sourceMap": "750:342:3:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;920:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;920:49:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;920:49:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1087:187:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1087:187:0;;;;;;;;;;;;;;;;;;;;;;;;;;;843:32:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;843:32:3;;;;;;;;;;;;;;;;;;;;1066:609:2;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1066:609:2;;;;;;;;;;;;;;802:35:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;802:35:3;;;;;;;;;;;;;;;;;;;;;;;982:99:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;982:99:0;;;;;;;975:37:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;975:37:3;;;;125:410:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;125:410:0;;;;;;;;;1280:126;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1280:126:0;;;;;;;;;;;;920:49:3;;;;;;;;;;;;;;;;;;;:::o;1087:187:0:-;1168:10;1144:4;1160:19;;;:7;:19;;;;;;;;;:29;;;;;;;;;;;:38;;;1208;;;;;;;1144:4;;1160:29;;1168:10;;1208:38;;;;;;;;-1:-1:-1;1263:4:0;1087:187;;;;;:::o;843:32:3:-;;;;:::o;1066:609:2:-;1198:14;;;1161:4;1198:14;;;:7;:14;;;;;;;;1213:10;1198:26;;;;;;;;1238:15;;;;;;;;;;1161:4;;1198:26;1238:25;-1:-1:-1;1238:25:2;;;:60;;;1292:6;1279:9;:19;;1238:60;:115;;;;-1:-1:-1;1340:13:2;;;:8;:13;;;;;;;;;;;1314:22;;;:39;;1238:115;1234:435;;;1378:13;;;;:8;:13;;;;;;;;;;;:23;;;;;;1415:15;;;;;;:25;;;;;;;768:10;1458:20;;1454:95;;;1498:14;;;;;;;:7;:14;;;;;;;;1513:10;1498:26;;;;;;;:36;;;;;;;1454:95;1578:3;1562:28;;1571:5;1562:28;;;1583:6;1562:28;;;;;;;;;;;;;;;;;;1611:4;1604:11;;;;1234:435;1653:5;1646:12;;1234:435;1066:609;;;;;;:::o;802:35:3:-;835:2;802:35;:::o;982:99:0:-;1058:16;;1035:4;1058:16;;;;;;;;;;;;982:99::o;975:37:3:-;;;;;;;;;;;;;;;;;;;:::o;125:410:0:-;276:10;178:4;267:20;;;;;;;;;;;:30;-1:-1:-1;267:30:0;;;:73;;-1:-1:-1;327:13:0;;;:8;:13;;;;;;;;;;;301:22;;;:39;;267:73;263:266;;;365:10;356:8;:20;;;;;;;;;;;:30;;;;;;;:20;400:13;;;;;;;;;:23;;;;;;437:33;;;;;;;400:13;;365:10;437:33;;;;;;;;;;;-1:-1:-1;491:4:0;484:11;;263:266;-1:-1:-1;521:5:0;514:12;;1280:126;1374:15;;;;1351:4;1374:15;;;:7;:15;;;;;;;;:25;;;;;;;;;;;;;1280:126::o" } } }, "sources": { - "current/tokens/ZRXToken/ZRXToken.sol": { + "1.0.0/ERC20Token/ERC20Token_v1.sol": { "id": 0 }, - "previous/ERC20Token/ERC20Token_v1.sol": { + "1.0.0/Token/Token_v1.sol": { "id": 1 }, - "previous/Token/Token_v1.sol": { + "1.0.0/UnlimitedAllowanceToken/UnlimitedAllowanceToken_v1.sol": { "id": 2 }, - "previous/UnlimitedAllowanceToken/UnlimitedAllowanceToken_v1.sol": { + "2.0.0/tokens/ZRXToken/ZRXToken.sol": { "id": 3 } }, "sourceCodes": { - "current/tokens/ZRXToken/ZRXToken.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity ^0.4.11;\n\nimport { UnlimitedAllowanceToken_v1 as UnlimitedAllowanceToken } from \"../../../previous/UnlimitedAllowanceToken/UnlimitedAllowanceToken_v1.sol\";\n\ncontract ZRXToken is UnlimitedAllowanceToken {\n\n uint8 constant public decimals = 18;\n uint public totalSupply = 10**27; // 1 billion tokens, 18 decimal places\n string constant public name = \"0x Protocol Token\";\n string constant public symbol = \"ZRX\";\n\n function ZRXToken() {\n balances[msg.sender] = totalSupply;\n }\n}\n", - "previous/ERC20Token/ERC20Token_v1.sol": "pragma solidity ^0.4.11;\n\nimport { Token_v1 as Token } from \"../Token/Token_v1.sol\";\n\ncontract ERC20Token_v1 is Token {\n\n function transfer(address _to, uint _value) returns (bool) {\n //Default assumes totalSupply can't be over max (2^256 - 1).\n if (balances[msg.sender] >= _value && balances[_to] + _value >= balances[_to]) {\n balances[msg.sender] -= _value;\n balances[_to] += _value;\n Transfer(msg.sender, _to, _value);\n return true;\n } else { return false; }\n }\n\n function transferFrom(address _from, address _to, uint _value) returns (bool) {\n if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value >= balances[_to]) {\n balances[_to] += _value;\n balances[_from] -= _value;\n allowed[_from][msg.sender] -= _value;\n Transfer(_from, _to, _value);\n return true;\n } else { return false; }\n }\n\n function balanceOf(address _owner) constant returns (uint) {\n return balances[_owner];\n }\n\n function approve(address _spender, uint _value) returns (bool) {\n allowed[msg.sender][_spender] = _value;\n Approval(msg.sender, _spender, _value);\n return true;\n }\n\n function allowance(address _owner, address _spender) constant returns (uint) {\n return allowed[_owner][_spender];\n }\n\n mapping (address => uint) balances;\n mapping (address => mapping (address => uint)) allowed;\n uint public totalSupply;\n}\n", - "previous/Token/Token_v1.sol": "pragma solidity ^0.4.11;\n\ncontract Token_v1 {\n\n /// @return total amount of tokens\n function totalSupply() constant returns (uint supply) {}\n\n /// @param _owner The address from which the balance will be retrieved\n /// @return The balance\n function balanceOf(address _owner) constant returns (uint balance) {}\n\n /// @notice send `_value` token to `_to` from `msg.sender`\n /// @param _to The address of the recipient\n /// @param _value The amount of token to be transferred\n /// @return Whether the transfer was successful or not\n function transfer(address _to, uint _value) returns (bool success) {}\n\n /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`\n /// @param _from The address of the sender\n /// @param _to The address of the recipient\n /// @param _value The amount of token to be transferred\n /// @return Whether the transfer was successful or not\n function transferFrom(address _from, address _to, uint _value) returns (bool success) {}\n\n /// @notice `msg.sender` approves `_addr` to spend `_value` tokens\n /// @param _spender The address of the account able to transfer the tokens\n /// @param _value The amount of wei to be approved for transfer\n /// @return Whether the approval was successful or not\n function approve(address _spender, uint _value) returns (bool success) {}\n\n /// @param _owner The address of the account owning tokens\n /// @param _spender The address of the account able to transfer the tokens\n /// @return Amount of remaining tokens allowed to spent\n function allowance(address _owner, address _spender) constant returns (uint remaining) {}\n\n event Transfer(address indexed _from, address indexed _to, uint _value);\n event Approval(address indexed _owner, address indexed _spender, uint _value);\n}\n\n", - "previous/UnlimitedAllowanceToken/UnlimitedAllowanceToken_v1.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity ^0.4.11;\n\nimport { ERC20Token_v1 as ERC20Token } from \"../ERC20Token/ERC20Token_v1.sol\";\n\ncontract UnlimitedAllowanceToken_v1 is ERC20Token {\n\n uint constant MAX_UINT = 2**256 - 1;\n\n /// @dev ERC20 transferFrom, modified such that an allowance of MAX_UINT represents an unlimited allowance.\n /// @param _from Address to transfer from.\n /// @param _to Address to transfer to.\n /// @param _value Amount to transfer.\n /// @return Success of transfer.\n function transferFrom(address _from, address _to, uint _value)\n public\n returns (bool)\n {\n uint allowance = allowed[_from][msg.sender];\n if (balances[_from] >= _value\n && allowance >= _value\n && balances[_to] + _value >= balances[_to]\n ) {\n balances[_to] += _value;\n balances[_from] -= _value;\n if (allowance < MAX_UINT) {\n allowed[_from][msg.sender] -= _value;\n }\n Transfer(_from, _to, _value);\n return true;\n } else {\n return false;\n }\n }\n}\n" + "1.0.0/ERC20Token/ERC20Token_v1.sol": "pragma solidity ^0.4.11;\n\nimport { Token_v1 as Token } from \"../Token/Token_v1.sol\";\n\ncontract ERC20Token_v1 is Token {\n\n function transfer(address _to, uint _value) returns (bool) {\n //Default assumes totalSupply can't be over max (2^256 - 1).\n if (balances[msg.sender] >= _value && balances[_to] + _value >= balances[_to]) {\n balances[msg.sender] -= _value;\n balances[_to] += _value;\n Transfer(msg.sender, _to, _value);\n return true;\n } else { return false; }\n }\n\n function transferFrom(address _from, address _to, uint _value) returns (bool) {\n if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value >= balances[_to]) {\n balances[_to] += _value;\n balances[_from] -= _value;\n allowed[_from][msg.sender] -= _value;\n Transfer(_from, _to, _value);\n return true;\n } else { return false; }\n }\n\n function balanceOf(address _owner) constant returns (uint) {\n return balances[_owner];\n }\n\n function approve(address _spender, uint _value) returns (bool) {\n allowed[msg.sender][_spender] = _value;\n Approval(msg.sender, _spender, _value);\n return true;\n }\n\n function allowance(address _owner, address _spender) constant returns (uint) {\n return allowed[_owner][_spender];\n }\n\n mapping (address => uint) balances;\n mapping (address => mapping (address => uint)) allowed;\n uint public totalSupply;\n}\n", + "1.0.0/Token/Token_v1.sol": "pragma solidity ^0.4.11;\n\ncontract Token_v1 {\n\n /// @return total amount of tokens\n function totalSupply() constant returns (uint supply) {}\n\n /// @param _owner The address from which the balance will be retrieved\n /// @return The balance\n function balanceOf(address _owner) constant returns (uint balance) {}\n\n /// @notice send `_value` token to `_to` from `msg.sender`\n /// @param _to The address of the recipient\n /// @param _value The amount of token to be transferred\n /// @return Whether the transfer was successful or not\n function transfer(address _to, uint _value) returns (bool success) {}\n\n /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`\n /// @param _from The address of the sender\n /// @param _to The address of the recipient\n /// @param _value The amount of token to be transferred\n /// @return Whether the transfer was successful or not\n function transferFrom(address _from, address _to, uint _value) returns (bool success) {}\n\n /// @notice `msg.sender` approves `_addr` to spend `_value` tokens\n /// @param _spender The address of the account able to transfer the tokens\n /// @param _value The amount of wei to be approved for transfer\n /// @return Whether the approval was successful or not\n function approve(address _spender, uint _value) returns (bool success) {}\n\n /// @param _owner The address of the account owning tokens\n /// @param _spender The address of the account able to transfer the tokens\n /// @return Amount of remaining tokens allowed to spent\n function allowance(address _owner, address _spender) constant returns (uint remaining) {}\n\n event Transfer(address indexed _from, address indexed _to, uint _value);\n event Approval(address indexed _owner, address indexed _spender, uint _value);\n}\n\n", + "1.0.0/UnlimitedAllowanceToken/UnlimitedAllowanceToken_v1.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity ^0.4.11;\n\nimport { ERC20Token_v1 as ERC20Token } from \"../ERC20Token/ERC20Token_v1.sol\";\n\ncontract UnlimitedAllowanceToken_v1 is ERC20Token {\n\n uint constant MAX_UINT = 2**256 - 1;\n\n /// @dev ERC20 transferFrom, modified such that an allowance of MAX_UINT represents an unlimited allowance.\n /// @param _from Address to transfer from.\n /// @param _to Address to transfer to.\n /// @param _value Amount to transfer.\n /// @return Success of transfer.\n function transferFrom(address _from, address _to, uint _value)\n public\n returns (bool)\n {\n uint allowance = allowed[_from][msg.sender];\n if (balances[_from] >= _value\n && allowance >= _value\n && balances[_to] + _value >= balances[_to]\n ) {\n balances[_to] += _value;\n balances[_from] -= _value;\n if (allowance < MAX_UINT) {\n allowed[_from][msg.sender] -= _value;\n }\n Transfer(_from, _to, _value);\n return true;\n } else {\n return false;\n }\n }\n}\n", + "2.0.0/tokens/ZRXToken/ZRXToken.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity ^0.4.11;\n\nimport { UnlimitedAllowanceToken_v1 as UnlimitedAllowanceToken } from \"../../../1.0.0/UnlimitedAllowanceToken/UnlimitedAllowanceToken_v1.sol\";\n\ncontract ZRXToken is UnlimitedAllowanceToken {\n\n uint8 constant public decimals = 18;\n uint public totalSupply = 10**27; // 1 billion tokens, 18 decimal places\n string constant public name = \"0x Protocol Token\";\n string constant public symbol = \"ZRX\";\n\n function ZRXToken() {\n balances[msg.sender] = totalSupply;\n }\n}\n" }, - "sourceTreeHashHex": "0xbaaa4c45ee7e505106ec3f265920d9be632c2dec05ba8ea8e7e7404805ee62a5", + "sourceTreeHashHex": "0xde47979523dda114901886ad7b4f9f43f0f3ccf10556e2b56d29370f0bc74d1d", "compiler": { "name": "solc", "version": "soljson-v0.4.24+commit.e67f0147.js", @@ -283,4 +283,4 @@ } }, "networks": {} -} +} \ No newline at end of file diff --git a/packages/web3-wrapper/src/index.ts b/packages/web3-wrapper/src/index.ts index b14fa7406..66ef0a784 100644 --- a/packages/web3-wrapper/src/index.ts +++ b/packages/web3-wrapper/src/index.ts @@ -1,2 +1,2 @@ -export { Web3Wrapper, uniqueVersionIds } from './web3_wrapper'; +export { Web3Wrapper, uniqueVersionIds, NodeType } from './web3_wrapper'; export { Web3WrapperErrors } from './types'; diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index 6ea69883c..e4df31def 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -31,6 +31,12 @@ export const uniqueVersionIds = { ganache: 'EthereumJS TestRPC', }; +// NodeType represents the type of the backing Ethereum node. +export enum NodeType { + Geth = 'GETH', + Ganache = 'GANACHE', +} + /** * A wrapper around the Web3.js 0.x library that provides a consistent, clean promise-based interface. */ @@ -489,6 +495,21 @@ export class Web3Wrapper { public async setHeadAsync(blockNumber: number): Promise { await this._sendRawPayloadAsync({ method: 'debug_setHead', params: [this._web3.toHex(blockNumber)] }); } + /** + * Returns either NodeType.Geth or NodeType.Ganache depending on the type of + * the backing Ethereum node. Throws for any other type of node. This + * function caches the result and so subsequent calls are fast. + */ + public async getNodeTypeAsync(): Promise { + const version = await this.getNodeVersionAsync(); + if (_.includes(version, uniqueVersionIds.geth)) { + return NodeType.Geth; + } else if (_.includes(version, uniqueVersionIds.ganache)) { + return NodeType.Ganache; + } else { + throw new Error(`Unknown client version: ${version}`); + } + } private async _sendRawPayloadAsync(payload: Partial): Promise { const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider); const payloadWithDefaults = { -- cgit v1.2.3 From 1a901554cceab03ead6129a1f41d87349fc3fe07 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 3 Jul 2018 15:39:15 +1000 Subject: compiler and ts lint are confused about ContractEventArgs --- .../src/order_watcher/order_watcher.ts | 31 ++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'packages') diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index d0acf2e6b..3418b4ee9 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -1,7 +1,10 @@ import { BalanceAndProxyAllowanceLazyStore, ContractWrappers, + LogCancelContractEventArgs, + LogFillContractEventArgs, OrderFilledCancelledLazyStore, + WithdrawalContractEventArgs, } from '@0xproject/contract-wrappers'; import { schemas } from '@0xproject/json-schemas'; import { getOrderHashHex, OrderStateUtils } from '@0xproject/order-utils'; @@ -19,9 +22,18 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import { artifacts } from '../artifacts'; -import { EtherTokenContractEventArgs, EtherTokenEvents } from '../generated_contract_wrappers/ether_token'; +import { + DepositContractEventArgs, + EtherTokenContractEventArgs, + EtherTokenEvents, +} from '../generated_contract_wrappers/ether_token'; import { ExchangeContractEventArgs, ExchangeEvents } from '../generated_contract_wrappers/exchange'; -import { TokenContractEventArgs, TokenEvents } from '../generated_contract_wrappers/token'; +import { + ApprovalContractEventArgs, + TokenContractEventArgs, + TokenEvents, + TransferContractEventArgs, +} from '../generated_contract_wrappers/token'; import { OnOrderStateChangeCallback, OrderWatcherConfig, OrderWatcherError } from '../types'; import { assert } from '../utils/assert'; @@ -237,7 +249,7 @@ export class OrderWatcher { switch (decodedLog.event) { case TokenEvents.Approval: { // Invalidate cache - const args = decodedLog.args; + const args = decodedLog.args as ApprovalContractEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; @@ -253,7 +265,7 @@ export class OrderWatcher { } case TokenEvents.Transfer: { // Invalidate cache - const args = decodedLog.args; + const args = decodedLog.args as TransferContractEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._from); this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._to); // Revalidate orders @@ -270,7 +282,7 @@ export class OrderWatcher { } case EtherTokenEvents.Deposit: { // Invalidate cache - const args = decodedLog.args; + const args = decodedLog.args as DepositContractEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; @@ -286,7 +298,8 @@ export class OrderWatcher { } case EtherTokenEvents.Withdrawal: { // Invalidate cache - const args = decodedLog.args; + // tslint:disable-next-line + const args = decodedLog.args as WithdrawalContractEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; @@ -302,7 +315,8 @@ export class OrderWatcher { } case ExchangeEvents.LogFill: { // Invalidate cache - const args = decodedLog.args; + // tslint:disable-next-line + const args = decodedLog.args as LogFillContractEventArgs; this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash); // Revalidate orders const orderHash = args.orderHash; @@ -314,7 +328,8 @@ export class OrderWatcher { } case ExchangeEvents.LogCancel: { // Invalidate cache - const args = decodedLog.args; + // tslint:disable-next-line + const args = decodedLog.args as LogCancelContractEventArgs; this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash); // Revalidate orders const orderHash = args.orderHash; -- cgit v1.2.3 From 27c03cffe2c1fe7f6c70cab286594840ef37d6e2 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 3 Jul 2018 17:01:08 +1000 Subject: Fix unused imports --- .../subproviders/src/subproviders/eth_lightwallet_subprovider.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'packages') diff --git a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts index 3cd94dac3..a9ebbb790 100644 --- a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts +++ b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts @@ -1,11 +1,6 @@ -import { assert } from '@0xproject/assert'; -import { addressUtils } from '@0xproject/utils'; import * as lightwallet from 'eth-lightwallet'; -import EthereumTx = require('ethereumjs-tx'); -import * as ethUtil from 'ethereumjs-util'; -import * as _ from 'lodash'; -import { PartialTxParams, WalletSubproviderErrors } from '../types'; +import { PartialTxParams } from '../types'; import { BaseWalletSubprovider } from './base_wallet_subprovider'; import { PrivateKeyWalletSubprovider } from './private_key_wallet'; -- cgit v1.2.3 From f2af6e4b3ae71abdd068a88bd5d686970649fe8d Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Tue, 3 Jul 2018 01:51:59 -0700 Subject: Add optional onClick to Link simple menu item --- packages/website/ts/components/ui/simple_menu.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/ui/simple_menu.tsx b/packages/website/ts/components/ui/simple_menu.tsx index c1cab07bd..74b8ef6ae 100644 --- a/packages/website/ts/components/ui/simple_menu.tsx +++ b/packages/website/ts/components/ui/simple_menu.tsx @@ -65,10 +65,15 @@ export const CopyAddressSimpleMenuItem: React.StatelessComponent = () => { +export interface GoToAccountManagementSimpleMenuItemProps { + onClick?: () => void; +} +export const GoToAccountManagementSimpleMenuItem: React.StatelessComponent< + GoToAccountManagementSimpleMenuItemProps +> = ({ onClick }) => { return ( - + ); }; -- cgit v1.2.3 From 4c99ac0ca2e758faf4f9fa8f9703cea357eb15aa Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 15:59:30 +0200 Subject: Update web3-provider-engine --- packages/contract-wrappers/package.json | 2 +- packages/dev-utils/package.json | 2 +- packages/metacoin/package.json | 2 +- packages/migrations/package.json | 2 +- packages/subproviders/package.json | 2 +- packages/testnet-faucets/package.json | 2 +- packages/website/package.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 1b4835be6..1408b4269 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -74,7 +74,7 @@ "source-map-support": "^0.5.0", "tslint": "5.8.0", "typescript": "2.7.1", - "web3-provider-engine": "^14.0.4" + "web3-provider-engine": "^14.0.6" }, "dependencies": { "@0xproject/assert": "^0.2.12", diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 621053ed7..00c6aa3fd 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -53,7 +53,7 @@ "@0xproject/web3-wrapper": "^0.7.1", "lodash": "^4.17.4", "web3": "^0.20.0", - "web3-provider-engine": "^14.0.4" + "web3-provider-engine": "^14.0.6" }, "publishConfig": { "access": "public" diff --git a/packages/metacoin/package.json b/packages/metacoin/package.json index 6b6ab9c40..db2f2eece 100644 --- a/packages/metacoin/package.json +++ b/packages/metacoin/package.json @@ -45,7 +45,7 @@ "ethers": "3.0.22", "lodash": "^4.17.4", "run-s": "^0.0.0", - "web3-provider-engine": "^14.0.4" + "web3-provider-engine": "^14.0.6" }, "devDependencies": { "@0xproject/dev-utils": "^0.4.4", diff --git a/packages/migrations/package.json b/packages/migrations/package.json index f4190a771..891dc6b1a 100644 --- a/packages/migrations/package.json +++ b/packages/migrations/package.json @@ -70,7 +70,7 @@ "ethereum-types": "^0.0.2", "ethers": "3.0.22", "lodash": "^4.17.4", - "web3-provider-engine": "^14.0.4" + "web3-provider-engine": "^14.0.6" }, "optionalDependencies": { "@ledgerhq/hw-transport-node-hid": "^4.3.0" diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index d15f80163..43508aa0f 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -56,7 +56,7 @@ "lodash": "^4.17.4", "semaphore-async-await": "^1.5.1", "web3": "^0.20.0", - "web3-provider-engine": "^14.0.4" + "web3-provider-engine": "^14.0.6" }, "devDependencies": { "@0xproject/monorepo-scripts": "^0.2.1", diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index fdd71656a..2e3668fdb 100644 --- a/packages/testnet-faucets/package.json +++ b/packages/testnet-faucets/package.json @@ -29,7 +29,7 @@ "lodash": "^4.17.4", "rollbar": "^0.6.5", "web3": "^0.20.0", - "web3-provider-engine": "^14.0.4" + "web3-provider-engine": "^14.0.6" }, "devDependencies": { "@0xproject/tslint-config": "^0.4.20", diff --git a/packages/website/package.json b/packages/website/package.json index cc7b7c05c..3b17fbf98 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -59,7 +59,7 @@ "thenby": "^1.2.3", "truffle-contract": "2.0.1", "web3": "^0.20.0", - "web3-provider-engine": "^14.0.4", + "web3-provider-engine": "^14.0.6", "whatwg-fetch": "^2.0.3", "xml-js": "^1.6.4" }, -- cgit v1.2.3 From 671f29774b9a46420fdee33e3ecbffc7fa6f4c1a Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 16:56:49 +0200 Subject: Update web3-provider-engine version w/o caret --- packages/contract-wrappers/package.json | 2 +- packages/dev-utils/package.json | 2 +- packages/metacoin/package.json | 2 +- packages/migrations/package.json | 2 +- packages/subproviders/package.json | 2 +- packages/testnet-faucets/package.json | 2 +- packages/website/package.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 1408b4269..449c64c2d 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -74,7 +74,7 @@ "source-map-support": "^0.5.0", "tslint": "5.8.0", "typescript": "2.7.1", - "web3-provider-engine": "^14.0.6" + "web3-provider-engine": "14.0.6" }, "dependencies": { "@0xproject/assert": "^0.2.12", diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 00c6aa3fd..74b585d36 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -53,7 +53,7 @@ "@0xproject/web3-wrapper": "^0.7.1", "lodash": "^4.17.4", "web3": "^0.20.0", - "web3-provider-engine": "^14.0.6" + "web3-provider-engine": "14.0.6" }, "publishConfig": { "access": "public" diff --git a/packages/metacoin/package.json b/packages/metacoin/package.json index db2f2eece..65372dd78 100644 --- a/packages/metacoin/package.json +++ b/packages/metacoin/package.json @@ -45,7 +45,7 @@ "ethers": "3.0.22", "lodash": "^4.17.4", "run-s": "^0.0.0", - "web3-provider-engine": "^14.0.6" + "web3-provider-engine": "14.0.6" }, "devDependencies": { "@0xproject/dev-utils": "^0.4.4", diff --git a/packages/migrations/package.json b/packages/migrations/package.json index 891dc6b1a..1cd8d209a 100644 --- a/packages/migrations/package.json +++ b/packages/migrations/package.json @@ -70,7 +70,7 @@ "ethereum-types": "^0.0.2", "ethers": "3.0.22", "lodash": "^4.17.4", - "web3-provider-engine": "^14.0.6" + "web3-provider-engine": "14.0.6" }, "optionalDependencies": { "@ledgerhq/hw-transport-node-hid": "^4.3.0" diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index 43508aa0f..23037df09 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -56,7 +56,7 @@ "lodash": "^4.17.4", "semaphore-async-await": "^1.5.1", "web3": "^0.20.0", - "web3-provider-engine": "^14.0.6" + "web3-provider-engine": "14.0.6" }, "devDependencies": { "@0xproject/monorepo-scripts": "^0.2.1", diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index 2e3668fdb..35b5c6805 100644 --- a/packages/testnet-faucets/package.json +++ b/packages/testnet-faucets/package.json @@ -29,7 +29,7 @@ "lodash": "^4.17.4", "rollbar": "^0.6.5", "web3": "^0.20.0", - "web3-provider-engine": "^14.0.6" + "web3-provider-engine": "14.0.6" }, "devDependencies": { "@0xproject/tslint-config": "^0.4.20", diff --git a/packages/website/package.json b/packages/website/package.json index 3b17fbf98..b9177bed2 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -59,7 +59,7 @@ "thenby": "^1.2.3", "truffle-contract": "2.0.1", "web3": "^0.20.0", - "web3-provider-engine": "^14.0.6", + "web3-provider-engine": "14.0.6", "whatwg-fetch": "^2.0.3", "xml-js": "^1.6.4" }, -- cgit v1.2.3 From afbfc8ba1c8d4bf812e3087db50c6a9dd786be79 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Tue, 3 Jul 2018 09:06:29 -0700 Subject: Implement clickaway for wallet menu on mobile --- packages/website/ts/components/ui/drop_down.tsx | 32 +++++++++++++++--------- packages/website/ts/components/wallet/wallet.tsx | 6 +++-- 2 files changed, 24 insertions(+), 14 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index c21c69993..4d5caef08 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -7,14 +7,20 @@ const DEFAULT_STYLE = { fontSize: 14, }; -interface DropDownProps { +export enum DropdownMouseEvent { + Hover = 'hover', + Click = 'click', +} + +export interface DropDownProps { activeNode: React.ReactNode; popoverContent: React.ReactNode; anchorOrigin: MaterialUIPosition; targetOrigin: MaterialUIPosition; style?: React.CSSProperties; zDepth?: number; - shouldWaitForClickToActivate?: boolean; + activateEvent?: DropdownMouseEvent; + closeEvent?: DropdownMouseEvent; } interface DropDownState { @@ -26,7 +32,8 @@ export class DropDown extends React.Component { public static defaultProps: Partial = { style: DEFAULT_STYLE, zDepth: 1, - shouldWaitForClickToActivate: false, + activateEvent: DropdownMouseEvent.Hover, + closeEvent: DropdownMouseEvent.Hover, }; private _isHovering: boolean; private _popoverCloseCheckIntervalId: number; @@ -67,7 +74,7 @@ export class DropDown extends React.Component { anchorOrigin={this.props.anchorOrigin} targetOrigin={this.props.targetOrigin} onRequestClose={this._closePopover.bind(this)} - useLayerForClickAway={false} + useLayerForClickAway={this.props.closeEvent === DropdownMouseEvent.Click} animated={false} zDepth={this.props.zDepth} > @@ -83,7 +90,7 @@ export class DropDown extends React.Component { ); } private _onActiveNodeClick(event: React.FormEvent): void { - if (this.props.shouldWaitForClickToActivate) { + if (this.props.activateEvent === DropdownMouseEvent.Click) { this.setState({ isDropDownOpen: true, anchorEl: event.currentTarget, @@ -92,28 +99,29 @@ export class DropDown extends React.Component { } private _onHover(event: React.FormEvent): void { this._isHovering = true; - if (!this.props.shouldWaitForClickToActivate) { + if (this.props.activateEvent === DropdownMouseEvent.Hover) { this._checkIfShouldOpenPopover(event); } } + private _onHoverOff(): void { + this._isHovering = false; + } private _checkIfShouldOpenPopover(event: React.FormEvent): void { if (this.state.isDropDownOpen) { return; // noop } - this.setState({ isDropDownOpen: true, anchorEl: event.currentTarget, }); } - private _onHoverOff(): void { - this._isHovering = false; - } private _checkIfShouldClosePopover(): void { - if (!this.state.isDropDownOpen || this._isHovering) { + if (!this.state.isDropDownOpen) { return; // noop } - this._closePopover(); + if (this.props.closeEvent === DropdownMouseEvent.Hover && !this._isHovering) { + this._closePopover(); + } } private _closePopover(): void { this.setState({ diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 875e6e78d..b891f873a 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -10,7 +10,7 @@ import firstBy = require('thenby'); import { Blockchain } from 'ts/blockchain'; import { AccountConnection } from 'ts/components/ui/account_connection'; import { Container } from 'ts/components/ui/container'; -import { DropDown } from 'ts/components/ui/drop_down'; +import { DropDown, DropdownMouseEvent } from 'ts/components/ui/drop_down'; import { IconButton } from 'ts/components/ui/icon_button'; import { Identicon } from 'ts/components/ui/identicon'; import { Island } from 'ts/components/ui/island'; @@ -194,6 +194,7 @@ export class Wallet extends React.Component { ); } private _renderConnectedHeaderRows(): React.ReactElement<{}> { + const isMobile = this.props.screenWidth === ScreenWidths.Sm; const userAddress = this.props.userAddress; const accountState = this._getAccountState(); const main = ( @@ -234,7 +235,8 @@ export class Wallet extends React.Component { anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} targetOrigin={{ horizontal: 'right', vertical: 'top' }} zDepth={1} - shouldWaitForClickToActivate={true} + activateEvent={DropdownMouseEvent.Click} + closeEvent={isMobile ? DropdownMouseEvent.Click : DropdownMouseEvent.Hover} /> ); return ( -- cgit v1.2.3 From 688b34710ea4b9262ac67d33b688751d5ca05a01 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 18:15:20 +0200 Subject: Update blockstream to latest version, propogate errors to top-level callers --- packages/contract-wrappers/CHANGELOG.json | 8 ++++++++ packages/contract-wrappers/package.json | 2 +- .../src/contract_wrappers/contract_wrapper.ts | 13 +++++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index 33d9bc4c0..e34b50c1a 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -1,4 +1,12 @@ [ + { + "version": "0.0.6", + "changes": [ + { + "note": "Update blockstream to v5.0 and propogate up caught errors to active subscriptions" + } + ] + }, { "timestamp": 1529397769, "version": "0.0.5", diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 449c64c2d..908f52a06 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -87,7 +87,7 @@ "@0xproject/utils": "^0.7.1", "@0xproject/web3-wrapper": "^0.7.1", "ethereum-types": "^0.0.2", - "ethereumjs-blockstream": "^2.0.6", + "ethereumjs-blockstream": "5.0.0", "ethereumjs-util": "^5.1.1", "ethers": "3.0.22", "js-sha3": "^0.7.0", diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts index 04f69bc3d..9cc661080 100644 --- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts @@ -9,7 +9,7 @@ import { } from '@0xproject/types'; import { intervalUtils } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import { Block, BlockAndLogStreamer } from 'ethereumjs-blockstream'; +import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream'; import * as _ from 'lodash'; import { @@ -39,7 +39,7 @@ export abstract class ContractWrapper { public abstract abi: ContractAbi; protected _web3Wrapper: Web3Wrapper; protected _networkId: number; - private _blockAndLogStreamerIfExists?: BlockAndLogStreamer; + private _blockAndLogStreamerIfExists: BlockAndLogStreamer | undefined; private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer; private _filters: { [filterToken: string]: FilterObject }; private _filterCallbacks: { @@ -163,6 +163,7 @@ export abstract class ContractWrapper { this._blockAndLogStreamerIfExists = new BlockAndLogStreamer( this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper), this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper), + this._onBlockAndLogStreamerError.bind(this), ); const catchAllLogFilter = {}; this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter); @@ -180,6 +181,14 @@ export abstract class ContractWrapper { this._onLogStateChanged.bind(this, isRemoved), ); } + private _onBlockAndLogStreamerError(err: Error): void { + // Propogate all Blockstream subscriber errors to all + // top-level subscriptions + const filterCallbacks = _.values(this._filterCallbacks); + _.each(filterCallbacks, filterCallback => { + filterCallback(err); + }); + } private _onReconcileBlockError(err: Error): void { const filterTokens = _.keys(this._filterCallbacks); _.each(filterTokens, filterToken => { -- cgit v1.2.3 From 2d30c290e9d5420ef6ec9b622ebddf3995239ebc Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Tue, 3 Jul 2018 09:22:52 -0700 Subject: Remove InstallPrompt --- .../ts/components/top_bar/install_prompt.tsx | 59 ---------------------- .../ts/components/top_bar/provider_display.tsx | 2 - 2 files changed, 61 deletions(-) delete mode 100644 packages/website/ts/components/top_bar/install_prompt.tsx (limited to 'packages') diff --git a/packages/website/ts/components/top_bar/install_prompt.tsx b/packages/website/ts/components/top_bar/install_prompt.tsx deleted file mode 100644 index 8d1a9c48a..000000000 --- a/packages/website/ts/components/top_bar/install_prompt.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import RaisedButton from 'material-ui/RaisedButton'; -import * as React from 'react'; - -import { colors } from 'ts/style/colors'; -import { constants } from 'ts/utils/constants'; - -export interface InstallPromptProps { - onToggleLedgerDialog: () => void; -} - -export const InstallPrompt: React.StatelessComponent = ({ onToggleLedgerDialog }) => { - return ( -
-
- Choose a wallet: -
-
- -
-
-
or
-
-
-
-
Connect to a ledger hardware wallet
-
- -
-
- -
-
-
-
- ); -}; diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 74f9beedb..46a32a238 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -6,7 +6,6 @@ import Lock from 'material-ui/svg-icons/action/lock'; import * as React from 'react'; import { Blockchain } from 'ts/blockchain'; -import { InstallPrompt } from 'ts/components/top_bar/install_prompt'; import { AccountConnection } from 'ts/components/ui/account_connection'; import { Container } from 'ts/components/ui/container'; import { DropDown } from 'ts/components/ui/drop_down'; @@ -81,7 +80,6 @@ export class ProviderDisplay extends React.Component ); case AccountState.Disconnected: - return ; case AccountState.Locked: case AccountState.Loading: default: -- cgit v1.2.3 From 5e8ef070e2255a1360753e81045cb42572e9c877 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 18:26:12 +0200 Subject: Fix alignment --- packages/contract-wrappers/package.json | 2 +- packages/dev-utils/package.json | 2 +- packages/metacoin/package.json | 2 +- packages/migrations/package.json | 2 +- packages/subproviders/package.json | 2 +- packages/testnet-faucets/package.json | 2 +- packages/website/package.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 908f52a06..373e023bd 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -74,7 +74,7 @@ "source-map-support": "^0.5.0", "tslint": "5.8.0", "typescript": "2.7.1", - "web3-provider-engine": "14.0.6" + "web3-provider-engine": "14.0.6" }, "dependencies": { "@0xproject/assert": "^0.2.12", diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 74b585d36..ebb2aeb41 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -53,7 +53,7 @@ "@0xproject/web3-wrapper": "^0.7.1", "lodash": "^4.17.4", "web3": "^0.20.0", - "web3-provider-engine": "14.0.6" + "web3-provider-engine": "14.0.6" }, "publishConfig": { "access": "public" diff --git a/packages/metacoin/package.json b/packages/metacoin/package.json index 65372dd78..3fa79387e 100644 --- a/packages/metacoin/package.json +++ b/packages/metacoin/package.json @@ -45,7 +45,7 @@ "ethers": "3.0.22", "lodash": "^4.17.4", "run-s": "^0.0.0", - "web3-provider-engine": "14.0.6" + "web3-provider-engine": "14.0.6" }, "devDependencies": { "@0xproject/dev-utils": "^0.4.4", diff --git a/packages/migrations/package.json b/packages/migrations/package.json index 1cd8d209a..a5fd3756a 100644 --- a/packages/migrations/package.json +++ b/packages/migrations/package.json @@ -70,7 +70,7 @@ "ethereum-types": "^0.0.2", "ethers": "3.0.22", "lodash": "^4.17.4", - "web3-provider-engine": "14.0.6" + "web3-provider-engine": "14.0.6" }, "optionalDependencies": { "@ledgerhq/hw-transport-node-hid": "^4.3.0" diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index 23037df09..a3ff31f53 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -56,7 +56,7 @@ "lodash": "^4.17.4", "semaphore-async-await": "^1.5.1", "web3": "^0.20.0", - "web3-provider-engine": "14.0.6" + "web3-provider-engine": "14.0.6" }, "devDependencies": { "@0xproject/monorepo-scripts": "^0.2.1", diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index 35b5c6805..0ec62f097 100644 --- a/packages/testnet-faucets/package.json +++ b/packages/testnet-faucets/package.json @@ -29,7 +29,7 @@ "lodash": "^4.17.4", "rollbar": "^0.6.5", "web3": "^0.20.0", - "web3-provider-engine": "14.0.6" + "web3-provider-engine": "14.0.6" }, "devDependencies": { "@0xproject/tslint-config": "^0.4.20", diff --git a/packages/website/package.json b/packages/website/package.json index b9177bed2..1bfc385b5 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -59,7 +59,7 @@ "thenby": "^1.2.3", "truffle-contract": "2.0.1", "web3": "^0.20.0", - "web3-provider-engine": "14.0.6", + "web3-provider-engine": "14.0.6", "whatwg-fetch": "^2.0.3", "xml-js": "^1.6.4" }, -- cgit v1.2.3 From c5fcea1dbd5e64e72eb5cf360558de9f9b886a16 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Tue, 3 Jul 2018 10:40:54 -0700 Subject: Actually cache node type in web3-wrapper --- packages/web3-wrapper/src/web3_wrapper.ts | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'packages') diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index e4df31def..c2754a13e 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -49,6 +49,7 @@ export class Web3Wrapper { private _web3: Web3; private _txDefaults: Partial; private _jsonRpcRequestId: number; + private _nodeType: NodeType | undefined; /** * Check if an address is a valid Ethereum address * @param address Address to check @@ -501,10 +502,15 @@ export class Web3Wrapper { * function caches the result and so subsequent calls are fast. */ public async getNodeTypeAsync(): Promise { + if (!_.isUndefined(this._nodeType)) { + return this._nodeType; + } const version = await this.getNodeVersionAsync(); if (_.includes(version, uniqueVersionIds.geth)) { + this._nodeType = NodeType.Geth; return NodeType.Geth; } else if (_.includes(version, uniqueVersionIds.ganache)) { + this._nodeType = NodeType.Ganache; return NodeType.Ganache; } else { throw new Error(`Unknown client version: ${version}`); -- cgit v1.2.3 From d2ebf4a7772070e3ec255d0551de8c9f2822d4c3 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Tue, 3 Jul 2018 10:49:35 -0700 Subject: Add TransactionReceiptStatus type to ethereum-types --- packages/contracts/test/utils/assertions.ts | 4 ++-- packages/ethereum-types/src/index.ts | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/contracts/test/utils/assertions.ts b/packages/contracts/test/utils/assertions.ts index 89e90ad2f..c8031c8a1 100644 --- a/packages/contracts/test/utils/assertions.ts +++ b/packages/contracts/test/utils/assertions.ts @@ -2,7 +2,7 @@ import { RevertReason } from '@0xproject/types'; import { logUtils } from '@0xproject/utils'; import { NodeType } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; -import { TransactionReceipt, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; +import { TransactionReceipt, TransactionReceiptStatus, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; import { web3Wrapper } from './web3_wrapper'; @@ -93,7 +93,7 @@ export async function expectTransactionFailedAsync(p: sendTransactionResult, rea export async function expectTransactionFailedWithoutReasonAsync(p: sendTransactionResult): Promise { return p .then(async result => { - let txReceiptStatus: null | string | 0 | 1; + let txReceiptStatus: TransactionReceiptStatus; if (_.isString(result)) { // Result is a txHash. We need to make a web3 call to get the // receipt, then get the status from the receipt. diff --git a/packages/ethereum-types/src/index.ts b/packages/ethereum-types/src/index.ts index 499c84327..f4d445e3b 100644 --- a/packages/ethereum-types/src/index.ts +++ b/packages/ethereum-types/src/index.ts @@ -215,6 +215,8 @@ export interface TxDataPayable extends TxData { value?: BigNumber; } +export type TransactionReceiptStatus = null | string | 0 | 1; + export interface TransactionReceipt { blockHash: string; blockNumber: number; @@ -222,7 +224,7 @@ export interface TransactionReceipt { transactionIndex: number; from: string; to: string; - status: null | string | 0 | 1; + status: TransactionReceiptStatus; cumulativeGasUsed: number; gasUsed: number; contractAddress: string | null; -- cgit v1.2.3 From ce1542da4fbab26d589f07f006fb5328a28bb9dd Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Tue, 3 Jul 2018 10:59:45 -0700 Subject: Update CHANGELOG.json for ethereum-types and web3-wrapper --- packages/ethereum-types/CHANGELOG.json | 4 ++++ packages/web3-wrapper/CHANGELOG.json | 10 ++++++++++ 2 files changed, 14 insertions(+) (limited to 'packages') diff --git a/packages/ethereum-types/CHANGELOG.json b/packages/ethereum-types/CHANGELOG.json index ad532062f..351e9c23f 100644 --- a/packages/ethereum-types/CHANGELOG.json +++ b/packages/ethereum-types/CHANGELOG.json @@ -5,6 +5,10 @@ { "note": "Add `TraceParams` interface for `debug_traceTransaction` parameters", "pr": 675 + }, + { + "note": "Add `TransactionReceiptStatus` type", + "pr": 812 } ] }, diff --git a/packages/web3-wrapper/CHANGELOG.json b/packages/web3-wrapper/CHANGELOG.json index 624ad7151..f8b1dab85 100644 --- a/packages/web3-wrapper/CHANGELOG.json +++ b/packages/web3-wrapper/CHANGELOG.json @@ -1,4 +1,14 @@ [ + { + "timestamp": 1529397769, + "version": "0.7.2", + "changes": [ + { + "note": "Add `getNodeTypeAsync` method", + "pr": 812 + } + ] + }, { "timestamp": 1529397769, "version": "0.7.1", -- cgit v1.2.3 From c30b42434a8999356d7537e50c88ea96481e8c60 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 3 Jul 2018 11:31:40 -0700 Subject: Fix linting --- packages/website/ts/components/onboarding/onboarding_flow.tsx | 3 +-- packages/website/ts/components/onboarding/portal_onboarding_flow.tsx | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 9abbc1c82..c2b4a4ca7 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -1,13 +1,12 @@ -import * as _ from 'lodash'; import * as React from 'react'; import { Placement, Popper, PopperChildrenProps } from 'react-popper'; import { OnboardingCard } from 'ts/components/onboarding/onboarding_card'; -import { PointerDirection } from 'ts/components/ui/pointer'; import { ContinueButtonDisplay, OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; import { Animation } from 'ts/components/ui/animation'; import { Container } from 'ts/components/ui/container'; import { Overlay } from 'ts/components/ui/overlay'; +import { PointerDirection } from 'ts/components/ui/pointer'; import { zIndex } from 'ts/style/z_index'; export interface FixedPositionSettings { diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 573196547..b7c5a9f64 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -10,10 +10,10 @@ import { CongratsOnboardingStep } from 'ts/components/onboarding/congrats_onboar import { InstallWalletOnboardingStep } from 'ts/components/onboarding/install_wallet_onboarding_step'; import { IntroOnboardingStep } from 'ts/components/onboarding/intro_onboarding_step'; import { + FixedPositionSettings, OnboardingFlow, Step, TargetPositionSettings, - FixedPositionSettings, } from 'ts/components/onboarding/onboarding_flow'; import { SetAllowancesOnboardingStep } from 'ts/components/onboarding/set_allowances_onboarding_step'; import { UnlockWalletOnboardingStep } from 'ts/components/onboarding/unlock_wallet_onboarding_step'; -- cgit v1.2.3 From 32c25a20341964498c3594758aa02908c98dbfc0 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 3 Jul 2018 11:48:34 -0700 Subject: Persist whether onboarding is open or close across refreshes --- packages/website/ts/redux/store.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/website/ts/redux/store.ts b/packages/website/ts/redux/store.ts index 0d0e6cea1..2672e3f61 100644 --- a/packages/website/ts/redux/store.ts +++ b/packages/website/ts/redux/store.ts @@ -13,9 +13,11 @@ export const store: ReduxStore = createStore( ); store.subscribe( _.throttle(() => { + const state = store.getState(); // Persisted state stateStorage.saveState({ - hasPortalOnboardingBeenClosed: store.getState().hasPortalOnboardingBeenClosed, + hasPortalOnboardingBeenClosed: state.hasPortalOnboardingBeenClosed, + isPortalOnboardingShowing: state.isPortalOnboardingShowing, }); }, ONE_SECOND), ); -- cgit v1.2.3 From dc956020ef7c6d3f1880263700422b31253c8da3 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Tue, 3 Jul 2018 12:55:05 -0700 Subject: Move NodeType caching out of web3-wrapper and into our internal code --- packages/contracts/test/utils/assertions.ts | 10 ++++++++-- packages/dev-utils/src/blockchain_lifecycle.ts | 12 ++++++++++-- packages/web3-wrapper/src/web3_wrapper.ts | 9 +-------- 3 files changed, 19 insertions(+), 12 deletions(-) (limited to 'packages') diff --git a/packages/contracts/test/utils/assertions.ts b/packages/contracts/test/utils/assertions.ts index c8031c8a1..112a470f6 100644 --- a/packages/contracts/test/utils/assertions.ts +++ b/packages/contracts/test/utils/assertions.ts @@ -9,12 +9,16 @@ import { web3Wrapper } from './web3_wrapper'; const expect = chai.expect; +let nodeType: NodeType | undefined; + // Represents the return value of a `sendTransaction` call. The Promise should // resolve with either a transaction receipt or a transaction hash. export type sendTransactionResult = Promise; async function _getGanacheOrGethError(ganacheError: string, gethError: string): Promise { - const nodeType = await web3Wrapper.getNodeTypeAsync(); + if (_.isUndefined(nodeType)) { + nodeType = await web3Wrapper.getNodeTypeAsync(); + } switch (nodeType) { case NodeType.Ganache: return ganacheError; @@ -68,7 +72,9 @@ export async function expectTransactionFailedAsync(p: sendTransactionResult, rea _.noop(e); }); - const nodeType = await web3Wrapper.getNodeTypeAsync(); + if (_.isUndefined(nodeType)) { + nodeType = await web3Wrapper.getNodeTypeAsync(); + } switch (nodeType) { case NodeType.Ganache: return expect(p).to.be.rejectedWith(reason); diff --git a/packages/dev-utils/src/blockchain_lifecycle.ts b/packages/dev-utils/src/blockchain_lifecycle.ts index abca6d386..9bd65ee5d 100644 --- a/packages/dev-utils/src/blockchain_lifecycle.ts +++ b/packages/dev-utils/src/blockchain_lifecycle.ts @@ -1,5 +1,6 @@ import { logUtils } from '@0xproject/utils'; import { NodeType, Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as _ from 'lodash'; // HACK(albrow): 🐉 We have to do this so that debug.setHead works correctly. // (Geth does not seem to like debug.setHead(0), so by sending some transactions @@ -12,12 +13,13 @@ export class BlockchainLifecycle { private _web3Wrapper: Web3Wrapper; private _snapshotIdsStack: number[]; private _addresses: string[] = []; + private _nodeType: NodeType | undefined; constructor(web3Wrapper: Web3Wrapper) { this._web3Wrapper = web3Wrapper; this._snapshotIdsStack = []; } public async startAsync(): Promise { - const nodeType = await this._web3Wrapper.getNodeTypeAsync(); + const nodeType = await this._getNodeTypeAsync(); switch (nodeType) { case NodeType.Ganache: const snapshotId = await this._web3Wrapper.takeSnapshotAsync(); @@ -38,7 +40,7 @@ export class BlockchainLifecycle { } } public async revertAsync(): Promise { - const nodeType = await this._web3Wrapper.getNodeTypeAsync(); + const nodeType = await this._getNodeTypeAsync(); switch (nodeType) { case NodeType.Ganache: const snapshotId = this._snapshotIdsStack.pop() as number; @@ -76,4 +78,10 @@ export class BlockchainLifecycle { } logUtils.warn('Done mining the minimum number of blocks.'); } + private async _getNodeTypeAsync(): Promise { + if (_.isUndefined(this._nodeType)) { + this._nodeType = await this._web3Wrapper.getNodeTypeAsync(); + } + return this._nodeType; + } } diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index c2754a13e..b79ade278 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -49,7 +49,6 @@ export class Web3Wrapper { private _web3: Web3; private _txDefaults: Partial; private _jsonRpcRequestId: number; - private _nodeType: NodeType | undefined; /** * Check if an address is a valid Ethereum address * @param address Address to check @@ -498,19 +497,13 @@ export class Web3Wrapper { } /** * Returns either NodeType.Geth or NodeType.Ganache depending on the type of - * the backing Ethereum node. Throws for any other type of node. This - * function caches the result and so subsequent calls are fast. + * the backing Ethereum node. Throws for any other type of node. */ public async getNodeTypeAsync(): Promise { - if (!_.isUndefined(this._nodeType)) { - return this._nodeType; - } const version = await this.getNodeVersionAsync(); if (_.includes(version, uniqueVersionIds.geth)) { - this._nodeType = NodeType.Geth; return NodeType.Geth; } else if (_.includes(version, uniqueVersionIds.ganache)) { - this._nodeType = NodeType.Ganache; return NodeType.Ganache; } else { throw new Error(`Unknown client version: ${version}`); -- cgit v1.2.3 From d528ce757c7d07e7d2e6f2f65ad48efc85ec4e50 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 22:58:17 +0200 Subject: Replace use of web3 w/ web3wrapper in subproviders and rename injectedWeb3 to signer subprovider for clarity --- packages/subproviders/package.json | 2 +- packages/subproviders/src/index.ts | 2 +- .../subproviders/src/subproviders/injected_web3.ts | 57 ----------------- packages/subproviders/src/subproviders/signer.ts | 74 ++++++++++++++++++++++ .../ts/containers/subproviders_documentation.ts | 3 + 5 files changed, 79 insertions(+), 59 deletions(-) delete mode 100644 packages/subproviders/src/subproviders/injected_web3.ts create mode 100644 packages/subproviders/src/subproviders/signer.ts (limited to 'packages') diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index a3ff31f53..2d939f7b4 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -42,6 +42,7 @@ "dependencies": { "@0xproject/assert": "^0.2.12", "@0xproject/types": "^0.8.1", + "@0xproject/web3-wrapper": "^0.7.1", "@0xproject/typescript-typings": "^0.4.2", "@0xproject/utils": "^0.7.1", "@ledgerhq/hw-app-eth": "^4.3.0", @@ -55,7 +56,6 @@ "hdkey": "^0.7.1", "lodash": "^4.17.4", "semaphore-async-await": "^1.5.1", - "web3": "^0.20.0", "web3-provider-engine": "14.0.6" }, "devDependencies": { diff --git a/packages/subproviders/src/index.ts b/packages/subproviders/src/index.ts index 9194c1341..8575cd07d 100644 --- a/packages/subproviders/src/index.ts +++ b/packages/subproviders/src/index.ts @@ -7,7 +7,7 @@ import { LedgerEthereumClient } from './types'; export { prependSubprovider } from './utils/subprovider_utils'; export { EmptyWalletSubprovider } from './subproviders/empty_wallet_subprovider'; export { FakeGasEstimateSubprovider } from './subproviders/fake_gas_estimate_subprovider'; -export { InjectedWeb3Subprovider } from './subproviders/injected_web3'; +export { SignerSubprovider } from './subproviders/signer'; export { RedundantSubprovider } from './subproviders/redundant_subprovider'; export { LedgerSubprovider } from './subproviders/ledger'; export { GanacheSubprovider } from './subproviders/ganache'; diff --git a/packages/subproviders/src/subproviders/injected_web3.ts b/packages/subproviders/src/subproviders/injected_web3.ts deleted file mode 100644 index 2691dec53..000000000 --- a/packages/subproviders/src/subproviders/injected_web3.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { JSONRPCRequestPayload, Provider } from 'ethereum-types'; -import * as Web3 from 'web3'; - -import { Callback, ErrorCallback } from '../types'; - -import { Subprovider } from './subprovider'; - -/** - * This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) - * subprovider interface. It forwards JSON RPC requests involving user accounts (getAccounts, - * sendTransaction, etc...) to the provider instance supplied at instantiation. All other requests - * are passed onwards for subsequent subproviders to handle. - */ -export class InjectedWeb3Subprovider extends Subprovider { - private _injectedWeb3: Web3; - /** - * Instantiates a new InjectedWeb3Subprovider - * @param provider Web3 provider that should handle all user account related requests - */ - constructor(provider: Provider) { - super(); - this._injectedWeb3 = new Web3(provider); - } - /** - * This method conforms to the web3-provider-engine interface. - * It is called internally by the ProviderEngine when it is this subproviders - * turn to handle a JSON RPC request. - * @param payload JSON RPC payload - * @param next Callback to call if this subprovider decides not to handle 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 - public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback): Promise { - switch (payload.method) { - case 'web3_clientVersion': - this._injectedWeb3.version.getNode(end); - return; - case 'eth_accounts': - this._injectedWeb3.eth.getAccounts(end); - return; - - case 'eth_sendTransaction': - const [txParams] = payload.params; - this._injectedWeb3.eth.sendTransaction(txParams, end); - return; - - case 'eth_sign': - const [address, message] = payload.params; - this._injectedWeb3.eth.sign(address, message, end); - return; - - default: - next(); - return; - } - } -} diff --git a/packages/subproviders/src/subproviders/signer.ts b/packages/subproviders/src/subproviders/signer.ts new file mode 100644 index 000000000..65b1f2635 --- /dev/null +++ b/packages/subproviders/src/subproviders/signer.ts @@ -0,0 +1,74 @@ +import { Web3Wrapper } from '@0project/web3-wrapper'; +import { JSONRPCRequestPayload, Provider } from 'ethereum-types'; + +import { Callback, ErrorCallback } from '../types'; + +import { Subprovider } from './subprovider'; + +/** + * This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) + * subprovider interface. It forwards JSON RPC requests involving the domain of a signer (getAccounts, + * sendTransaction, signMessage etc...) to the provider instance supplied at instantiation. All other requests + * are passed onwards for subsequent subproviders to handle. + */ +export class SignerSubprovider extends Subprovider { + private _SignerWrapper: Web3Wrapper; + /** + * Instantiates a new SignerSubprovider + * @param provider Web3 provider that should handle all user account related requests + */ + constructor(provider: Provider) { + super(); + this._SignerWrapper = new Web3Wrapper(provider); + } + /** + * This method conforms to the web3-provider-engine interface. + * It is called internally by the ProviderEngine when it is this subproviders + * turn to handle a JSON RPC request. + * @param payload JSON RPC payload + * @param next Callback to call if this subprovider decides not to handle 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 + public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback): Promise { + switch (payload.method) { + case 'web3_clientVersion': + try { + const nodeVersion = await this._SignerWrapper.getNodeVersionAsync(); + end(null, nodeVersion); + } catch (err) { + end(err); + } + return; + case 'eth_accounts': + try { + const accounts = await this._SignerWrapper.getAvailableAddressesAsync(); + end(null, accounts); + } catch (err) { + end(err); + } + return; + case 'eth_sendTransaction': + const [txParams] = payload.params; + try { + const txHash = await this._SignerWrapper.sendTransactionAsync(txParams); + end(null, txHash); + } catch (err) { + end(err); + } + return; + case 'eth_sign': + const [address, message] = payload.params; + try { + const signature = await this._SignerWrapper.signMessageAsync(address, message); + end(null, signature); + } catch (err) { + end(err); + } + return; + default: + next(); + return; + } + } +} diff --git a/packages/website/ts/containers/subproviders_documentation.ts b/packages/website/ts/containers/subproviders_documentation.ts index 6d4230e53..567f6a37e 100644 --- a/packages/website/ts/containers/subproviders_documentation.ts +++ b/packages/website/ts/containers/subproviders_documentation.ts @@ -25,6 +25,7 @@ const docSections = { emptyWalletSubprovider: 'emptyWalletSubprovider', fakeGasEstimateSubprovider: 'fakeGasEstimateSubprovider', injectedWeb3Subprovider: 'injectedWeb3Subprovider', + signerSubprovider: 'signerSubprovider', redundantRPCSubprovider: 'redundantRPCSubprovider', ganacheSubprovider: 'ganacheSubprovider', nonceTrackerSubprovider: 'nonceTrackerSubprovider', @@ -50,6 +51,7 @@ const docsInfoConfig: DocsInfoConfig = { ['emptyWallet-subprovider']: [docSections.emptyWalletSubprovider], ['fakeGasEstimate-subprovider']: [docSections.fakeGasEstimateSubprovider], ['injectedWeb3-subprovider']: [docSections.injectedWeb3Subprovider], + ['signer-subprovider']: [docSections.signerSubprovider], ['redundantRPC-subprovider']: [docSections.redundantRPCSubprovider], ['ganache-subprovider']: [docSections.ganacheSubprovider], ['nonceTracker-subprovider']: [docSections.nonceTrackerSubprovider], @@ -69,6 +71,7 @@ const docsInfoConfig: DocsInfoConfig = { [docSections.emptyWalletSubprovider]: ['"subproviders/src/subproviders/empty_wallet_subprovider"'], [docSections.fakeGasEstimateSubprovider]: ['"subproviders/src/subproviders/fake_gas_estimate_subprovider"'], [docSections.injectedWeb3Subprovider]: ['"subproviders/src/subproviders/injected_web3"'], + [docSections.signerSubprovider]: ['"subproviders/src/subproviders/signer"'], [docSections.redundantRPCSubprovider]: ['"subproviders/src/subproviders/redundant_rpc"'], [docSections.ganacheSubprovider]: ['"subproviders/src/subproviders/ganache"'], [docSections.nonceTrackerSubprovider]: ['"subproviders/src/subproviders/nonce_tracker"'], -- cgit v1.2.3 From 547cf4bef3f2c18a26fb9fada96bd92e7988687f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 23:11:49 +0200 Subject: Refactor testnet-faucet to use web3Wrapper instead of web3 directly --- packages/testnet-faucets/package.json | 2 +- packages/testnet-faucets/src/ts/dispense_asset_tasks.ts | 13 ++++++------- packages/testnet-faucets/src/ts/handler.ts | 17 ++++++----------- 3 files changed, 13 insertions(+), 19 deletions(-) (limited to 'packages') diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index 0ec62f097..5acd4ae35 100644 --- a/packages/testnet-faucets/package.json +++ b/packages/testnet-faucets/package.json @@ -20,6 +20,7 @@ "dependencies": { "0x.js": "^0.38.0", "@0xproject/subproviders": "^0.10.4", + "@0xproject/web3-wrapper": "^0.7.1", "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", "body-parser": "^1.17.1", @@ -28,7 +29,6 @@ "express": "^4.15.2", "lodash": "^4.17.4", "rollbar": "^0.6.5", - "web3": "^0.20.0", "web3-provider-engine": "14.0.6" }, "devDependencies": { diff --git a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts index 41b6c90cd..6e41ddae3 100644 --- a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts +++ b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts @@ -1,7 +1,7 @@ import { ZeroEx } from '0x.js'; import { BigNumber, logUtils, promisify } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; -import * as Web3 from 'web3'; import { configs } from './configs'; @@ -13,22 +13,21 @@ const DISPENSE_MAX_AMOUNT_ETHER = 2; type AsyncTask = () => Promise; export const dispenseAssetTasks = { - dispenseEtherTask(recipientAddress: string, web3: Web3): AsyncTask { + dispenseEtherTask(recipientAddress: string, web3Wrapper: Web3Wrapper): AsyncTask { return async () => { logUtils.log(`Processing ETH ${recipientAddress}`); - const userBalance = await promisify(web3.eth.getBalance)(recipientAddress); - const maxAmountInWei = new BigNumber(web3.toWei(DISPENSE_MAX_AMOUNT_ETHER, 'ether')); + const userBalance = await web3Wrapper.getBalanceInWeiAsync(recipientAddress); + const maxAmountInWei = Web3Wrapper.toWei(new BigNumber(DISPENSE_MAX_AMOUNT_ETHER)); if (userBalance.greaterThanOrEqualTo(maxAmountInWei)) { logUtils.log( `User exceeded ETH balance maximum (${maxAmountInWei}) ${recipientAddress} ${userBalance} `, ); return; } - const sendTransactionAsync = promisify(web3.eth.sendTransaction); - const txHash = await sendTransactionAsync({ + const txHash = await web3Wrapper.sendTransactionAsync({ from: configs.DISPENSER_ADDRESS, to: recipientAddress, - value: web3.toWei(DISPENSE_AMOUNT_ETHER, 'ether'), + value: Web3Wrapper.toWei(new BigNumber(DISPENSE_AMOUNT_ETHER)), }); logUtils.log(`Sent ${DISPENSE_AMOUNT_ETHER} ETH to ${recipientAddress} tx: ${txHash}`); }; diff --git a/packages/testnet-faucets/src/ts/handler.ts b/packages/testnet-faucets/src/ts/handler.ts index 3a60d396c..6d26691d6 100644 --- a/packages/testnet-faucets/src/ts/handler.ts +++ b/packages/testnet-faucets/src/ts/handler.ts @@ -1,15 +1,10 @@ import { Order, ZeroEx } from '0x.js'; import { BigNumber, logUtils } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { Provider } from 'ethereum-types'; import * as express from 'express'; import * as _ from 'lodash'; -import * as Web3 from 'web3'; -// HACK: web3 injects XMLHttpRequest into the global scope and ProviderEngine checks XMLHttpRequest -// to know whether it is running in a browser or node environment. We need it to be undefined since -// we are not running in a browser env. -// Filed issue: https://github.com/ethereum/web3.js/issues/844 -(global as any).XMLHttpRequest = undefined; import { NonceTrackerSubprovider, PrivateKeyWalletSubprovider } from '@0xproject/subproviders'; import ProviderEngine = require('web3-provider-engine'); import RpcSubprovider = require('web3-provider-engine/subproviders/rpc'); @@ -22,7 +17,7 @@ import { rpcUrls } from './rpc_urls'; interface NetworkConfig { dispatchQueue: DispatchQueue; - web3: Web3; + web3Wrapper: Web3Wrapper; zeroEx: ZeroEx; } @@ -58,15 +53,15 @@ export class Handler { constructor() { _.forIn(rpcUrls, (rpcUrl: string, networkId: string) => { const providerObj = Handler._createProviderEngine(rpcUrl); - const web3 = new Web3(providerObj); + const web3Wrapper = new Web3Wrapper(providerObj); const zeroExConfig = { networkId: +networkId, }; - const zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig); + const zeroEx = new ZeroEx(providerObj, zeroExConfig); const dispatchQueue = new DispatchQueue(); this._networkConfigByNetworkId[networkId] = { dispatchQueue, - web3, + web3Wrapper, zeroEx, }; }); @@ -106,7 +101,7 @@ export class Handler { let dispenserTask; switch (requestedAssetType) { case RequestedAssetType.ETH: - dispenserTask = dispenseAssetTasks.dispenseEtherTask(recipient, networkConfig.web3); + dispenserTask = dispenseAssetTasks.dispenseEtherTask(recipient, networkConfig.web3Wrapper); break; case RequestedAssetType.WETH: case RequestedAssetType.ZRX: -- cgit v1.2.3 From cce2fb40a130edfd5116d74b294b5e8062751ffb Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 23:11:59 +0200 Subject: Fix import --- packages/subproviders/src/subproviders/signer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/subproviders/src/subproviders/signer.ts b/packages/subproviders/src/subproviders/signer.ts index 65b1f2635..e436c7855 100644 --- a/packages/subproviders/src/subproviders/signer.ts +++ b/packages/subproviders/src/subproviders/signer.ts @@ -1,4 +1,4 @@ -import { Web3Wrapper } from '@0project/web3-wrapper'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { JSONRPCRequestPayload, Provider } from 'ethereum-types'; import { Callback, ErrorCallback } from '../types'; -- cgit v1.2.3 From d09711363951f7ae25b3b3d5e091df7a420caf9f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 23:34:51 +0200 Subject: Remove dep on Web3 in Website. Introduced InjectedWeb3 type. --- packages/website/package.json | 1 - packages/website/ts/blockchain.ts | 24 +++++++++++++++++------- packages/website/ts/types.ts | 9 +++++++++ packages/website/ts/utils/analytics.ts | 11 ++++++----- 4 files changed, 32 insertions(+), 13 deletions(-) (limited to 'packages') diff --git a/packages/website/package.json b/packages/website/package.json index 1bfc385b5..a5768a60b 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -58,7 +58,6 @@ "styled-components": "^3.3.0", "thenby": "^1.2.3", "truffle-contract": "2.0.1", - "web3": "^0.20.0", "web3-provider-engine": "14.0.6", "whatwg-fetch": "^2.0.3", "xml-js": "^1.6.4" diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index b59306974..a93ec9331 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -46,6 +46,7 @@ import { Fill, InjectedProviderObservable, InjectedProviderUpdate, + InjectedWeb3, Order as PortalOrder, Providers, ProviderType, @@ -59,7 +60,6 @@ import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { errorReporter } from 'ts/utils/error_reporter'; import { utils } from 'ts/utils/utils'; -import Web3 = require('web3'); import ProviderEngine = require('web3-provider-engine'); import FilterSubprovider = require('web3-provider-engine/subproviders/filters'); import RpcSubprovider = require('web3-provider-engine/subproviders/rpc'); @@ -97,8 +97,18 @@ export class Blockchain { } return providerNameIfExists; } - private static _getInjectedWeb3(): any { - return (window as any).web3; + private static _getInjectedWeb3(): InjectedWeb3 { + const injectedWeb3IfExists = (window as any).web3; + // Our core assumptions about the injected web3 object is that it has the following + // properties and methods. + if ( + !_.isUndefined(injectedWeb3IfExists.version) && + !_.isUndefined(injectedWeb3IfExists.version.getNetwork) && + !_.isUndefined(injectedWeb3IfExists.currentProvider) + ) { + return undefined; + } + return injectedWeb3IfExists; } private static async _getInjectedWeb3ProviderNetworkIdIfExistsAsync(): Promise { // Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in @@ -119,7 +129,7 @@ export class Blockchain { return networkIdIfExists; } private static async _getProviderAsync( - injectedWeb3: Web3, + injectedWeb3: InjectedWeb3, networkIdIfExists: number, shouldUserLedgerProvider: boolean = false, ): Promise<[Provider, LedgerSubprovider | undefined]> { @@ -834,10 +844,10 @@ export class Blockchain { this._dispatcher.updateNetworkId(networkId); await this._rehydrateStoreWithContractEventsAsync(); } - private _updateProviderName(injectedWeb3: Web3): void { - const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3); + private _updateProviderName(injectedWeb3IfExists: InjectedWeb3): void { + const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3IfExists); const providerName = doesInjectedWeb3Exist - ? Blockchain._getNameGivenProvider(injectedWeb3.currentProvider) + ? Blockchain._getNameGivenProvider(injectedWeb3IfExists.currentProvider) : constants.PROVIDER_NAME_PUBLIC; this._dispatcher.updateInjectedProviderName(providerName); } diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 2e4cf84d0..1239958df 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -1,5 +1,6 @@ import { ECSignature } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; +import { Provider } from 'ethereum-types'; import * as React from 'react'; export enum Side { @@ -573,4 +574,12 @@ export enum AccountState { Loading = 'Loading', Locked = 'Locked', } + +// Minimal interface expected for an injected web3 object +export interface InjectedWeb3 { + currentProvider: Provider; + version: { + getNetwork(cd: (err: Error, networkId: string) => void): void; + }; +} // tslint:disable:max-file-line-count diff --git a/packages/website/ts/utils/analytics.ts b/packages/website/ts/utils/analytics.ts index 928e45bc3..f4bfa083f 100644 --- a/packages/website/ts/utils/analytics.ts +++ b/packages/website/ts/utils/analytics.ts @@ -1,8 +1,8 @@ import * as _ from 'lodash'; import * as ReactGA from 'react-ga'; +import { InjectedWeb3 } from 'ts/types'; import { configs } from 'ts/utils/configs'; import { utils } from 'ts/utils/utils'; -import * as Web3 from 'web3'; export const analytics = { init(): void { @@ -16,11 +16,12 @@ export const analytics = { value, }); }, - async logProviderAsync(web3IfExists: Web3): Promise { + async logProviderAsync(web3IfExists: InjectedWeb3): Promise { await utils.onPageLoadAsync(); - const providerType = !_.isUndefined(web3IfExists) - ? utils.getProviderType(web3IfExists.currentProvider) - : 'NONE'; + const providerType = + !_.isUndefined(web3IfExists) && !_.isUndefined(web3IfExists.currentProvider) + ? utils.getProviderType(web3IfExists.currentProvider) + : 'NONE'; ReactGA.ga('set', 'dimension1', providerType); }, }; -- cgit v1.2.3 From a5653337c1e52cfe95befbbf3924f97cb462846f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 23:36:14 +0200 Subject: Remove unused imported Web3.js --- packages/contracts/package.json | 3 +-- packages/dev-utils/package.json | 1 - packages/sol-compiler/package.json | 1 - packages/utils/package.json | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) (limited to 'packages') diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 01f2320d0..448871c23 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -85,7 +85,6 @@ "ethereumjs-abi": "^0.6.4", "ethereumjs-util": "^5.1.1", "ethers": "3.0.22", - "lodash": "^4.17.4", - "web3": "^0.20.0" + "lodash": "^4.17.4" } } diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index ebb2aeb41..15f8d6ab0 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -52,7 +52,6 @@ "@0xproject/typescript-typings": "^0.4.1", "@0xproject/web3-wrapper": "^0.7.1", "lodash": "^4.17.4", - "web3": "^0.20.0", "web3-provider-engine": "14.0.6" }, "publishConfig": { diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json index 2c1fa41b3..d5a2e6e77 100644 --- a/packages/sol-compiler/package.json +++ b/packages/sol-compiler/package.json @@ -93,7 +93,6 @@ "require-from-string": "^2.0.1", "semver": "^5.5.0", "solc": "^0.4.23", - "web3": "^0.20.0", "web3-eth-abi": "^1.0.0-beta.24", "yargs": "^10.0.3" }, diff --git a/packages/utils/package.json b/packages/utils/package.json index f10594de5..f08586b4d 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -43,7 +43,6 @@ "ethers": "3.0.22", "js-sha3": "^0.7.0", "lodash": "^4.17.4", - "web3": "^0.20.0" }, "publishConfig": { "access": "public" -- cgit v1.2.3 From 2b4bb579d47037fa8c8a2c858bc467ccd8eed3b0 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 23:57:19 +0200 Subject: Rename subprovider in blockchain.ts --- packages/website/ts/blockchain.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index a93ec9331..8f1b33aeb 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -12,10 +12,10 @@ import { import { isValidOrderHash, signOrderHashAsync } from '@0xproject/order-utils'; import { EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; import { - InjectedWeb3Subprovider, ledgerEthereumBrowserClientFactoryAsync, LedgerSubprovider, RedundantSubprovider, + SignerSubprovider, Subprovider, } from '@0xproject/subproviders'; import { @@ -163,7 +163,7 @@ export class Blockchain { // We catch all requests involving a users account and send it to the injectedWeb3 // instance. All other requests go to the public hosted node. const provider = new ProviderEngine(); - provider.addProvider(new InjectedWeb3Subprovider(injectedWeb3.currentProvider)); + provider.addProvider(new SignerSubprovider(injectedWeb3.currentProvider)); provider.addProvider(new FilterSubprovider()); const rpcSubproviders = _.map(publicNodeUrlsIfExistsForNetworkId, publicNodeUrl => { return new RpcSubprovider({ -- cgit v1.2.3 From a7902eca1f6e6e89c6dd81c1705dc313433d2a2e Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 3 Jul 2018 23:57:33 +0200 Subject: Fix package.json --- packages/utils/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/utils/package.json b/packages/utils/package.json index f08586b4d..0ba7a7ba4 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -42,7 +42,7 @@ "bignumber.js": "~4.1.0", "ethers": "3.0.22", "js-sha3": "^0.7.0", - "lodash": "^4.17.4", + "lodash": "^4.17.4" }, "publishConfig": { "access": "public" -- cgit v1.2.3 From 54c0b7b261277e8fe1a221a9aa21dbd5364e4ba6 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 4 Jul 2018 00:13:36 +0200 Subject: Fix type --- packages/website/ts/types.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 1239958df..b241a34bc 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -575,9 +575,13 @@ export enum AccountState { Locked = 'Locked', } +export interface MetamaskProvider extends Provider { + publicConfigStore: InjectedProviderObservable; +} + // Minimal interface expected for an injected web3 object export interface InjectedWeb3 { - currentProvider: Provider; + currentProvider: MetamaskProvider; version: { getNetwork(cd: (err: Error, networkId: string) => void): void; }; -- cgit v1.2.3 From f5cd1ac82eeaef97cb668ff6d622407f54ac165a Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 4 Jul 2018 00:18:09 +0200 Subject: Fix linter --- packages/testnet-faucets/src/ts/dispense_asset_tasks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts index 6e41ddae3..3af5ca747 100644 --- a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts +++ b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts @@ -1,5 +1,5 @@ import { ZeroEx } from '0x.js'; -import { BigNumber, logUtils, promisify } from '@0xproject/utils'; +import { BigNumber, logUtils } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; -- cgit v1.2.3 From 6aa4984fed55be7ba4fe0caf0f994a11bccdc155 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 4 Jul 2018 00:22:21 +0200 Subject: Fix instance variable name --- packages/subproviders/src/subproviders/signer.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'packages') diff --git a/packages/subproviders/src/subproviders/signer.ts b/packages/subproviders/src/subproviders/signer.ts index e436c7855..08a9daceb 100644 --- a/packages/subproviders/src/subproviders/signer.ts +++ b/packages/subproviders/src/subproviders/signer.ts @@ -12,14 +12,14 @@ import { Subprovider } from './subprovider'; * are passed onwards for subsequent subproviders to handle. */ export class SignerSubprovider extends Subprovider { - private _SignerWrapper: Web3Wrapper; + private _web3Wrapper: Web3Wrapper; /** * Instantiates a new SignerSubprovider * @param provider Web3 provider that should handle all user account related requests */ constructor(provider: Provider) { super(); - this._SignerWrapper = new Web3Wrapper(provider); + this._web3Wrapper = new Web3Wrapper(provider); } /** * This method conforms to the web3-provider-engine interface. @@ -34,7 +34,7 @@ export class SignerSubprovider extends Subprovider { switch (payload.method) { case 'web3_clientVersion': try { - const nodeVersion = await this._SignerWrapper.getNodeVersionAsync(); + const nodeVersion = await this._web3Wrapper.getNodeVersionAsync(); end(null, nodeVersion); } catch (err) { end(err); @@ -42,7 +42,7 @@ export class SignerSubprovider extends Subprovider { return; case 'eth_accounts': try { - const accounts = await this._SignerWrapper.getAvailableAddressesAsync(); + const accounts = await this._web3Wrapper.getAvailableAddressesAsync(); end(null, accounts); } catch (err) { end(err); @@ -51,7 +51,7 @@ export class SignerSubprovider extends Subprovider { case 'eth_sendTransaction': const [txParams] = payload.params; try { - const txHash = await this._SignerWrapper.sendTransactionAsync(txParams); + const txHash = await this._web3Wrapper.sendTransactionAsync(txParams); end(null, txHash); } catch (err) { end(err); @@ -60,7 +60,7 @@ export class SignerSubprovider extends Subprovider { case 'eth_sign': const [address, message] = payload.params; try { - const signature = await this._SignerWrapper.signMessageAsync(address, message); + const signature = await this._web3Wrapper.signMessageAsync(address, message); end(null, signature); } catch (err) { end(err); -- cgit v1.2.3 From 5f2c303bd8ce983533863b54e14856b39b578035 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 4 Jul 2018 00:23:40 +0200 Subject: Remove hack since latest web3-provider-engine fixed underlying issue --- packages/dev-utils/src/web3_factory.ts | 5 ----- 1 file changed, 5 deletions(-) (limited to 'packages') diff --git a/packages/dev-utils/src/web3_factory.ts b/packages/dev-utils/src/web3_factory.ts index 47eef4cbd..362a6c3c6 100644 --- a/packages/dev-utils/src/web3_factory.ts +++ b/packages/dev-utils/src/web3_factory.ts @@ -1,8 +1,3 @@ -// HACK: web3 injects XMLHttpRequest into the global scope and ProviderEngine checks XMLHttpRequest -// to know whether it is running in a browser or node environment. We need it to be undefined since -// we are not running in a browser env. -// Filed issue: https://github.com/ethereum/web3.js/issues/844 -(global as any).XMLHttpRequest = undefined; import ProviderEngine = require('web3-provider-engine'); import RpcSubprovider = require('web3-provider-engine/subproviders/rpc'); -- cgit v1.2.3 From f4109034656fa826e25d0d4ba8a9d5e676f6c786 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 4 Jul 2018 00:29:29 +0200 Subject: Rename to InjectedProvider and make publicConfigStore optional --- packages/website/ts/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index b241a34bc..be33f130c 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -575,13 +575,13 @@ export enum AccountState { Locked = 'Locked', } -export interface MetamaskProvider extends Provider { - publicConfigStore: InjectedProviderObservable; +export interface InjectedProvider extends Provider { + publicConfigStore?: InjectedProviderObservable; } // Minimal interface expected for an injected web3 object export interface InjectedWeb3 { - currentProvider: MetamaskProvider; + currentProvider: InjectedProvider; version: { getNetwork(cd: (err: Error, networkId: string) => void): void; }; -- cgit v1.2.3 From 9db0bc262ba85d7dc3b104a0c1c81f85e985acfb Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 4 Jul 2018 00:36:57 +0200 Subject: Fix conditional --- packages/website/ts/blockchain.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index 8f1b33aeb..eb2cba268 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -102,9 +102,9 @@ export class Blockchain { // Our core assumptions about the injected web3 object is that it has the following // properties and methods. if ( - !_.isUndefined(injectedWeb3IfExists.version) && - !_.isUndefined(injectedWeb3IfExists.version.getNetwork) && - !_.isUndefined(injectedWeb3IfExists.currentProvider) + _.isUndefined(injectedWeb3IfExists.version) || + _.isUndefined(injectedWeb3IfExists.version.getNetwork) || + _.isUndefined(injectedWeb3IfExists.currentProvider) ) { return undefined; } @@ -787,6 +787,7 @@ export class Blockchain { const networkIdIfExists = await Blockchain._getInjectedWeb3ProviderNetworkIdIfExistsAsync(); this.networkId = !_.isUndefined(networkIdIfExists) ? networkIdIfExists : constants.NETWORK_ID_MAINNET; const injectedWeb3IfExists = Blockchain._getInjectedWeb3(); + console.log(injectedWeb3IfExists); if (!_.isUndefined(injectedWeb3IfExists) && !_.isUndefined(injectedWeb3IfExists.currentProvider)) { const injectedProviderObservable = injectedWeb3IfExists.currentProvider.publicConfigStore; if (!_.isUndefined(injectedProviderObservable) && _.isUndefined(this._injectedProviderObservable)) { -- cgit v1.2.3 From 0d56daf7ab71031edfa5145704a9a9b746fd80cf Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 4 Jul 2018 00:37:39 +0200 Subject: remove console.log --- packages/website/ts/blockchain.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages') diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index eb2cba268..6a92403f2 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -787,7 +787,6 @@ export class Blockchain { const networkIdIfExists = await Blockchain._getInjectedWeb3ProviderNetworkIdIfExistsAsync(); this.networkId = !_.isUndefined(networkIdIfExists) ? networkIdIfExists : constants.NETWORK_ID_MAINNET; const injectedWeb3IfExists = Blockchain._getInjectedWeb3(); - console.log(injectedWeb3IfExists); if (!_.isUndefined(injectedWeb3IfExists) && !_.isUndefined(injectedWeb3IfExists.currentProvider)) { const injectedProviderObservable = injectedWeb3IfExists.currentProvider.publicConfigStore; if (!_.isUndefined(injectedProviderObservable) && _.isUndefined(this._injectedProviderObservable)) { -- cgit v1.2.3 From 8ff17ff9603f6b574e76f5ef160fe59c3afb2a86 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 4 Jul 2018 00:41:19 +0200 Subject: improve comment --- packages/website/ts/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index be33f130c..512167ed1 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -579,7 +579,7 @@ export interface InjectedProvider extends Provider { publicConfigStore?: InjectedProviderObservable; } -// Minimal interface expected for an injected web3 object +// Minimal expected interface for an injected web3 object export interface InjectedWeb3 { currentProvider: InjectedProvider; version: { -- cgit v1.2.3 From 4ba108d12f857ae29c5f5d46fec005027609666d Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 4 Jul 2018 00:59:18 +0200 Subject: Use stub in test to avoid difference in setup, how network requests take place --- packages/subproviders/package.json | 2 ++ packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts | 5 +++++ 2 files changed, 7 insertions(+) (limited to 'packages') diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index a3ff31f53..8634341ae 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -69,6 +69,7 @@ "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", "@types/node": "^8.0.53", + "@types/sinon": "^2.2.2", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", "copyfiles": "^1.2.0", @@ -78,6 +79,7 @@ "npm-run-all": "^4.1.2", "nyc": "^11.0.1", "shx": "^0.2.2", + "sinon": "^4.0.0", "tslint": "5.8.0", "typedoc": "0xProject/typedoc", "typescript": "2.7.1", diff --git a/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts b/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts index 593027849..810fb8f45 100644 --- a/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts +++ b/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts @@ -1,6 +1,7 @@ import { DoneCallback } from '@0xproject/types'; import * as chai from 'chai'; import { JSONRPCResponsePayload } from 'ethereum-types'; +import * as Sinon from 'sinon'; import Web3ProviderEngine = require('web3-provider-engine'); import RpcSubprovider = require('web3-provider-engine/subproviders/rpc'); @@ -41,6 +42,9 @@ describe('RedundantSubprovider', () => { const nonExistentSubprovider = new RpcSubprovider({ rpcUrl: 'http://does-not-exist:3000', }); + const handleRequestStub = Sinon.stub(nonExistentSubprovider, 'handleRequest').throws( + new Error('REQUEST_FAILED'), + ); const subproviders = [nonExistentSubprovider as Subprovider, ganacheSubprovider]; const redundantSubprovider = new RedundantSubprovider(subproviders); provider.addProvider(redundantSubprovider); @@ -55,6 +59,7 @@ describe('RedundantSubprovider', () => { const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { expect(err).to.be.a('null'); expect(response.result.length).to.be.equal(DEFAULT_NUM_ACCOUNTS); + handleRequestStub.restore(); done(); }); provider.sendAsync(payload, callback); -- cgit v1.2.3 From 9e0f06d06055022fff80bbf7a8b6444f72f898ec Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 4 Jul 2018 20:06:10 +1000 Subject: Specify the lint rule to disable --- packages/order-watcher/src/order_watcher/order_watcher.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index 3418b4ee9..0ee56592e 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -298,7 +298,7 @@ export class OrderWatcher { } case EtherTokenEvents.Withdrawal: { // Invalidate cache - // tslint:disable-next-line + // tslint:disable-next-line:no-unnecessary-type-assertion const args = decodedLog.args as WithdrawalContractEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner); // Revalidate orders @@ -315,7 +315,7 @@ export class OrderWatcher { } case ExchangeEvents.LogFill: { // Invalidate cache - // tslint:disable-next-line + // tslint:disable-next-line:no-unnecessary-type-assertion const args = decodedLog.args as LogFillContractEventArgs; this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash); // Revalidate orders @@ -328,7 +328,7 @@ export class OrderWatcher { } case ExchangeEvents.LogCancel: { // Invalidate cache - // tslint:disable-next-line + // tslint:disable-next-line:no-unnecessary-type-assertion const args = decodedLog.args as LogCancelContractEventArgs; this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash); // Revalidate orders -- cgit v1.2.3 From 4e783fba57bbd3d389ab52679ca8763bfa03cbf3 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 4 Jul 2018 16:34:03 +0200 Subject: Add missing undefined check --- packages/website/ts/blockchain.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages') diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index 6a92403f2..cc2afa28a 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -102,6 +102,7 @@ export class Blockchain { // Our core assumptions about the injected web3 object is that it has the following // properties and methods. if ( + _.isUndefined(injectedWeb3IfExists) || _.isUndefined(injectedWeb3IfExists.version) || _.isUndefined(injectedWeb3IfExists.version.getNetwork) || _.isUndefined(injectedWeb3IfExists.currentProvider) -- cgit v1.2.3