diff options
Diffstat (limited to 'packages/order-watcher')
28 files changed, 428 insertions, 307 deletions
diff --git a/packages/order-watcher/.npmignore b/packages/order-watcher/.npmignore index c5be1b302..ac4ab11f2 100644 --- a/packages/order-watcher/.npmignore +++ b/packages/order-watcher/.npmignore @@ -7,4 +7,3 @@ test/ /_bundles/ /generated_docs/ /scripts/ -/lib/src/monorepo_scripts/ diff --git a/packages/order-watcher/CHANGELOG.json b/packages/order-watcher/CHANGELOG.json index 6a365f314..d574f4a18 100644 --- a/packages/order-watcher/CHANGELOG.json +++ b/packages/order-watcher/CHANGELOG.json @@ -1,5 +1,129 @@ [ { + "version": "2.2.0", + "changes": [ + { + "note": "Added getStats function and returns a Stats object", + "pr": 1118 + }, + { + "note": + "Updated to use new modularized artifacts and the latest version of @0xproject/contract-wrappers. Constructor has a new optional `contractAddresses` parameter.", + "pr": 1105 + } + ], + "timestamp": 1539871071 + }, + { + "version": "2.1.1", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1538693146 + }, + { + "version": "2.1.0", + "changes": [ + { + "note": "Export ExpirationWatcher", + "pr": 1097 + } + ], + "timestamp": 1538157789 + }, + { + "version": "2.0.0", + "changes": [ + { + "note": + "Fixes dropped events issue by fetching logs by blockHash instead of blockNumber. Support for fetching by blockHash was added in Geth > v1.8.13 and Parity > v2.1.0. Infura works too.", + "pr": 1080 + }, + { + "note": + "Fix misunderstanding about blockstream interface callbacks and pass the raw JSON RPC responses to it", + "pr": 1080 + }, + { + "note": + "Add `transactionHash` to `OrderState` emitted by `OrderWatcher` subscriptions if the order's state change originated from a transaction.", + "pr": 1087 + } + ], + "timestamp": 1537907159 + }, + { + "version": "1.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1537875740 + }, + { + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1537541580 + }, + { + "version": "1.0.3", + "changes": [ + { + "note": "Drastically reduce the bundle size by removing unused parts of included contract artifacts." + } + ], + "timestamp": 1537369748 + }, + { + "version": "1.0.2", + "changes": [ + { + "note": "Add ZRX & WETH mainnet contract addresses into the included artifacts" + } + ], + "timestamp": 1537265493 + }, + { + "timestamp": 1536142250, + "version": "1.0.1", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "version": "1.0.1-rc.5", + "changes": [ + { + "note": "Fix missing `BlockParamLiteral` type import issue" + } + ], + "timestamp": 1535377027 + }, + { + "version": "1.0.1-rc.4", + "changes": [ + { + "note": + "Export types: `ExchangeContractErrs`, `OrderRelevantState`, `JSONRPCRequestPayload`, `JSONRPCErrorCallback` and `JSONRPCResponsePayload`", + "pr": 924 + }, + { + "note": "Remove exporting types: `BlockParamLiteral`, `BlockParam`, `Order`", + "pr": 924 + } + ], + "timestamp": 1535133899 + }, + { "version": "1.0.1-rc.3", "changes": [ { diff --git a/packages/order-watcher/CHANGELOG.md b/packages/order-watcher/CHANGELOG.md index bb92f2850..299af5437 100644 --- a/packages/order-watcher/CHANGELOG.md +++ b/packages/order-watcher/CHANGELOG.md @@ -5,7 +5,55 @@ Edit the package's CHANGELOG.json file only. CHANGELOG -## v1.0.1-rc.3 - _August 13, 2018_ +## v2.2.0 - _October 18, 2018_ + + * Added getStats function and returns a Stats object (#1118) + * Updated to use new modularized artifacts and the latest version of @0xproject/contract-wrappers. Constructor has a new optional `contractAddresses` parameter. (#1105) + +## v2.1.1 - _October 4, 2018_ + + * Dependencies updated + +## v2.1.0 - _September 28, 2018_ + + * Export ExpirationWatcher (#1097) + +## v2.0.0 - _September 25, 2018_ + + * Fixes dropped events issue by fetching logs by blockHash instead of blockNumber. Support for fetching by blockHash was added in Geth > v1.8.13 and Parity > v2.1.0. Infura works too. (#1080) + * Fix misunderstanding about blockstream interface callbacks and pass the raw JSON RPC responses to it (#1080) + * Add `transactionHash` to `OrderState` emitted by `OrderWatcher` subscriptions if the order's state change originated from a transaction. (#1087) + +## v1.0.5 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.4 - _September 21, 2018_ + + * Dependencies updated + +## v1.0.3 - _September 19, 2018_ + + * Drastically reduce the bundle size by removing unused parts of included contract artifacts. + +## v1.0.2 - _September 18, 2018_ + + * Add ZRX & WETH mainnet contract addresses into the included artifacts + +## v1.0.1 - _September 5, 2018_ + + * Dependencies updated + +## v1.0.1-rc.5 - _August 27, 2018_ + + * Fix missing `BlockParamLiteral` type import issue + +## v1.0.1-rc.4 - _August 24, 2018_ + + * Export types: `ExchangeContractErrs`, `OrderRelevantState`, `JSONRPCRequestPayload`, `JSONRPCErrorCallback` and `JSONRPCResponsePayload` (#924) + * Remove exporting types: `BlockParamLiteral`, `BlockParam`, `Order` (#924) + +## v1.0.1-rc.3 - _August 14, 2018_ * Dependencies updated diff --git a/packages/order-watcher/README.md b/packages/order-watcher/README.md index de64a70e7..c0b99b272 100644 --- a/packages/order-watcher/README.md +++ b/packages/order-watcher/README.md @@ -9,20 +9,20 @@ An order watcher daemon that watches for order validity. **Install** ```bash -npm install @0xproject/order-watcher --save +npm install @0x/order-watcher --save ``` **Import** ```javascript -import { OrderWatcher } from '@0xproject/order-watcher'; +import { OrderWatcher } from '@0x/order-watcher'; ``` If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`: ```json "compilerOptions": { - "typeRoots": ["node_modules/@0xproject/typescript-typings/types", "node_modules/@types"], + "typeRoots": ["node_modules/@0x/typescript-typings/types", "node_modules/@types"], } ``` @@ -51,13 +51,13 @@ yarn install To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory: ```bash -PKG=@0xproject/order-watcher yarn build +PKG=@0x/order-watcher yarn build ``` Or continuously rebuild on change: ```bash -PKG=@0xproject/order-watcher yarn watch +PKG=@0x/order-watcher yarn watch ``` ### Clean diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json index 9c8f7f411..42e3f572c 100644 --- a/packages/order-watcher/package.json +++ b/packages/order-watcher/package.json @@ -1,6 +1,6 @@ { - "name": "@0xproject/order-watcher", - "version": "1.0.1-rc.3", + "name": "@0x/order-watcher", + "version": "2.2.0", "description": "An order watcher daemon that watches for order validity", "keywords": [ "0x", @@ -12,24 +12,17 @@ "main": "lib/src/index.js", "types": "lib/src/index.d.ts", "scripts": { - "watch_without_deps": "yarn pre_build && tsc -w", - "build": "yarn pre_build && tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", - "pre_build": "run-s update_artifacts copy_artifacts generate_contract_wrappers", - "lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/*", - "generate_contract_wrappers": "abi-gen --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers", + "build": "yarn tsc -b", + "build:ci": "yarn build", + "lint": "tslint --format stylish --project .", "test:circleci": "run-s test:coverage", "test": "yarn run_mocha", "rebuild_and_test": "run-s build test", "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", - "copy_artifacts": "copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts", - "update_artifacts": "for i in ${npm_package_config_contracts_v2_beta}; do copyfiles -u 4 ../migrations/artifacts/2.0.0-beta-testnet/$i.json src/artifacts; done;", - "clean": "shx rm -rf _bundles lib test_temp scripts test/artifacts src/generated_contract_wrappers", + "clean": "shx rm -rf _bundles lib test_temp generated_docs", "run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit", - "manual:postpublish": "yarn build; node ./scripts/postpublish.js" - }, - "config": { - "contracts_v2_beta": "AssetProxyOwner ERC20Proxy ERC20Token ERC721Proxy ERC721Token Exchange Forwarder WETH9 ZRXToken" + "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" }, "repository": { "type": "git", @@ -40,24 +33,18 @@ "node": ">=6.0.0" }, "devDependencies": { - "@0xproject/abi-gen": "^1.0.5", - "@0xproject/dev-utils": "^1.0.4", - "@0xproject/migrations": "^1.0.4", - "@0xproject/monorepo-scripts": "^1.0.5", - "@0xproject/sol-compiler": "^1.0.5", - "@0xproject/tslint-config": "^1.0.5", + "@0x/dev-utils": "^1.0.13", + "@0x/migrations": "^2.0.0", + "@0x/tslint-config": "^1.0.9", "@types/bintrees": "^1.0.2", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/sinon": "^2.2.2", - "awesome-typescript-loader": "^3.1.3", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.1", - "copyfiles": "^2.0.0", "dirty-chai": "^2.0.1", - "json-loader": "^0.5.4", "make-promises-safe": "^1.1.0", "mocha": "^4.1.0", "npm-run-all": "^4.1.2", @@ -70,20 +57,23 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/assert": "^1.0.5", - "@0xproject/base-contract": "^2.0.0-rc.1", - "@0xproject/contract-wrappers": "^1.0.1-rc.3", - "@0xproject/fill-scenarios": "^1.0.1-rc.3", - "@0xproject/json-schemas": "^1.0.1-rc.4", - "@0xproject/order-utils": "^1.0.1-rc.3", - "@0xproject/types": "^1.0.1-rc.4", - "@0xproject/typescript-typings": "^1.0.4", - "@0xproject/utils": "^1.0.5", - "@0xproject/web3-wrapper": "^1.2.0", + "@0x/abi-gen-wrappers": "^1.0.1", + "@0x/assert": "^1.0.14", + "@0x/base-contract": "^3.0.2", + "@0x/contract-addresses": "^1.0.1", + "@0x/contract-artifacts": "^1.0.1", + "@0x/contract-wrappers": "^3.0.0", + "@0x/fill-scenarios": "^1.0.8", + "@0x/json-schemas": "^2.0.0", + "@0x/order-utils": "^2.0.0", + "@0x/types": "^1.2.0", + "@0x/typescript-typings": "^3.0.3", + "@0x/utils": "^2.0.3", + "@0x/web3-wrapper": "^3.1.0", "bintrees": "^1.0.2", - "ethereum-types": "^1.0.4", - "ethereumjs-blockstream": "5.0.0", - "ethers": "3.0.22", + "ethereum-types": "^1.1.1", + "ethereumjs-blockstream": "6.0.0", + "ethers": "~4.0.4", "lodash": "^4.17.5" }, "publishConfig": { diff --git a/packages/order-watcher/src/artifacts.ts b/packages/order-watcher/src/artifacts.ts deleted file mode 100644 index d47e619c2..000000000 --- a/packages/order-watcher/src/artifacts.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ContractArtifact } from '@0xproject/sol-compiler'; - -import * as ERC20Token from './artifacts/ERC20Token.json'; -import * as ERC721Token from './artifacts/ERC721Token.json'; -import * as Exchange from './artifacts/Exchange.json'; -import * as WETH9 from './artifacts/WETH9.json'; - -export const artifacts = { - ERC20Token: (ERC20Token as any) as ContractArtifact, - ERC721Token: (ERC721Token as any) as ContractArtifact, - Exchange: (Exchange as any) as ContractArtifact, - EtherToken: (WETH9 as any) as ContractArtifact, -}; diff --git a/packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts b/packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts deleted file mode 100644 index a1de22a5e..000000000 --- a/packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts +++ /dev/null @@ -1,74 +0,0 @@ -// tslint:disable:no-unnecessary-type-assertion -import { BlockParamLiteral, ERC20TokenWrapper, ERC721TokenWrapper } from '@0xproject/contract-wrappers'; -import { AbstractBalanceAndProxyAllowanceFetcher, assetDataUtils } from '@0xproject/order-utils'; -import { AssetProxyId, ERC20AssetData, ERC721AssetData } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; - -export class AssetBalanceAndProxyAllowanceFetcher implements AbstractBalanceAndProxyAllowanceFetcher { - private readonly _erc20Token: ERC20TokenWrapper; - private readonly _erc721Token: ERC721TokenWrapper; - private readonly _stateLayer: BlockParamLiteral; - constructor(erc20Token: ERC20TokenWrapper, erc721Token: ERC721TokenWrapper, stateLayer: BlockParamLiteral) { - this._erc20Token = erc20Token; - this._erc721Token = erc721Token; - this._stateLayer = stateLayer; - } - public async getBalanceAsync(assetData: string, userAddress: string): Promise<BigNumber> { - const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); - if (decodedAssetData.assetProxyId === AssetProxyId.ERC20) { - const decodedERC20AssetData = decodedAssetData as ERC20AssetData; - const balance = await this._erc20Token.getBalanceAsync(decodedERC20AssetData.tokenAddress, userAddress, { - defaultBlock: this._stateLayer, - }); - return balance; - } else { - const decodedERC721AssetData = decodedAssetData as ERC721AssetData; - const tokenOwner = await this._erc721Token.getOwnerOfAsync( - decodedERC721AssetData.tokenAddress, - decodedERC721AssetData.tokenId, - { - defaultBlock: this._stateLayer, - }, - ); - const balance = tokenOwner === userAddress ? new BigNumber(1) : new BigNumber(0); - return balance; - } - } - public async getProxyAllowanceAsync(assetData: string, userAddress: string): Promise<BigNumber> { - const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); - if (decodedAssetData.assetProxyId === AssetProxyId.ERC20) { - const decodedERC20AssetData = decodedAssetData as ERC20AssetData; - const proxyAllowance = await this._erc20Token.getProxyAllowanceAsync( - decodedERC20AssetData.tokenAddress, - userAddress, - { - defaultBlock: this._stateLayer, - }, - ); - return proxyAllowance; - } else { - const decodedERC721AssetData = decodedAssetData as ERC721AssetData; - - const isApprovedForAll = await this._erc721Token.isProxyApprovedForAllAsync( - decodedERC721AssetData.tokenAddress, - userAddress, - { - defaultBlock: this._stateLayer, - }, - ); - if (isApprovedForAll) { - return new BigNumber(this._erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); - } else { - const isApproved = await this._erc721Token.isProxyApprovedAsync( - decodedERC721AssetData.tokenAddress, - decodedERC721AssetData.tokenId, - { - defaultBlock: this._stateLayer, - }, - ); - const proxyAllowance = isApproved ? new BigNumber(1) : new BigNumber(0); - return proxyAllowance; - } - } - } -} diff --git a/packages/order-watcher/src/fetchers/order_filled_cancelled_fetcher.ts b/packages/order-watcher/src/fetchers/order_filled_cancelled_fetcher.ts deleted file mode 100644 index bfad1a48c..000000000 --- a/packages/order-watcher/src/fetchers/order_filled_cancelled_fetcher.ts +++ /dev/null @@ -1,27 +0,0 @@ -// tslint:disable:no-unnecessary-type-assertion -import { BlockParamLiteral, ExchangeWrapper } from '@0xproject/contract-wrappers'; -import { AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils'; -import { BigNumber } from '@0xproject/utils'; - -export class OrderFilledCancelledFetcher implements AbstractOrderFilledCancelledFetcher { - private readonly _exchange: ExchangeWrapper; - private readonly _stateLayer: BlockParamLiteral; - constructor(exchange: ExchangeWrapper, stateLayer: BlockParamLiteral) { - this._exchange = exchange; - this._stateLayer = stateLayer; - } - public async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber> { - const filledTakerAmount = this._exchange.getFilledTakerAssetAmountAsync(orderHash, { - defaultBlock: this._stateLayer, - }); - return filledTakerAmount; - } - public async isOrderCancelledAsync(orderHash: string): Promise<boolean> { - const isCancelled = await this._exchange.isCancelledAsync(orderHash); - return isCancelled; - } - public getZRXAssetData(): string { - const zrxAssetData = this._exchange.getZRXAssetData(); - return zrxAssetData; - } -} diff --git a/packages/order-watcher/src/globals.d.ts b/packages/order-watcher/src/globals.d.ts deleted file mode 100644 index 94e63a32d..000000000 --- a/packages/order-watcher/src/globals.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare module '*.json' { - const json: any; - /* tslint:disable */ - export default json; - /* tslint:enable */ -} diff --git a/packages/order-watcher/src/index.ts b/packages/order-watcher/src/index.ts index 5f84554c8..5eeba3e87 100644 --- a/packages/order-watcher/src/index.ts +++ b/packages/order-watcher/src/index.ts @@ -1,8 +1,23 @@ export { OrderWatcher } from './order_watcher/order_watcher'; +export { ExpirationWatcher } from './order_watcher/expiration_watcher'; -export { OrderStateValid, OrderStateInvalid, OrderState } from '@0xproject/types'; +export { + OrderStateValid, + OrderStateInvalid, + OrderState, + ExchangeContractErrs, + OrderRelevantState, + Stats, +} from '@0x/types'; export { OnOrderStateChangeCallback, OrderWatcherConfig } from './types'; -export { Order, SignedOrder } from '@0xproject/types'; -export { BlockParamLiteral, BlockParam, Provider } from 'ethereum-types'; +export { ContractAddresses } from '@0x/contract-addresses'; +export { SignedOrder } from '@0x/types'; +export { + JSONRPCRequestPayload, + JSONRPCErrorCallback, + Provider, + JSONRPCResponsePayload, + JSONRPCResponseError, +} from 'ethereum-types'; diff --git a/packages/order-watcher/src/monorepo_scripts/postpublish.ts b/packages/order-watcher/src/monorepo_scripts/postpublish.ts deleted file mode 100644 index dcb99d0f7..000000000 --- a/packages/order-watcher/src/monorepo_scripts/postpublish.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { postpublishUtils } from '@0xproject/monorepo-scripts'; - -import * as packageJSON from '../package.json'; -import * as tsConfigJSON from '../tsconfig.json'; - -const cwd = `${__dirname}/..`; -// tslint:disable-next-line:no-floating-promises -postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd); diff --git a/packages/order-watcher/src/order_watcher/collision_resistant_abi_decoder.ts b/packages/order-watcher/src/order_watcher/collision_resistant_abi_decoder.ts index e13663c7a..2ea796947 100644 --- a/packages/order-watcher/src/order_watcher/collision_resistant_abi_decoder.ts +++ b/packages/order-watcher/src/order_watcher/collision_resistant_abi_decoder.ts @@ -1,4 +1,4 @@ -import { AbiDecoder } from '@0xproject/utils'; +import { AbiDecoder } from '@0x/utils'; import { ContractAbi, DecodedLogArgs, LogEntry, LogWithDecodedArgs, RawLog } from 'ethereum-types'; const TOKEN_TYPE_COLLISION = `Token can't be marked as ERC20 and ERC721 at the same time`; diff --git a/packages/order-watcher/src/order_watcher/dependent_order_hashes_tracker.ts b/packages/order-watcher/src/order_watcher/dependent_order_hashes_tracker.ts index cc70bd5d7..dbcc25186 100644 --- a/packages/order-watcher/src/order_watcher/dependent_order_hashes_tracker.ts +++ b/packages/order-watcher/src/order_watcher/dependent_order_hashes_tracker.ts @@ -1,7 +1,7 @@ // tslint:disable:no-unnecessary-type-assertion -import { assetDataUtils, orderHashUtils } from '@0xproject/order-utils'; -import { AssetProxyId, ERC20AssetData, ERC721AssetData, SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; +import { assetDataUtils, orderHashUtils } from '@0x/order-utils'; +import { AssetProxyId, ERC20AssetData, ERC721AssetData, SignedOrder } from '@0x/types'; +import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; export interface OrderHashesByMakerAddress { diff --git a/packages/order-watcher/src/order_watcher/event_watcher.ts b/packages/order-watcher/src/order_watcher/event_watcher.ts index 9509c75de..3149d858b 100644 --- a/packages/order-watcher/src/order_watcher/event_watcher.ts +++ b/packages/order-watcher/src/order_watcher/event_watcher.ts @@ -1,6 +1,6 @@ -import { intervalUtils, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import { BlockParamLiteral, LogEntry, Provider } from 'ethereum-types'; +import { intervalUtils, logUtils } from '@0x/utils'; +import { marshaller, Web3Wrapper } from '@0x/web3-wrapper'; +import { BlockParamLiteral, FilterObject, LogEntry, Provider, RawLogEntry } from 'ethereum-types'; import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream'; import * as _ from 'lodash'; @@ -20,7 +20,6 @@ enum LogEventState { */ export class EventWatcher { private readonly _web3Wrapper: Web3Wrapper; - private readonly _stateLayer: BlockParamLiteral; private readonly _isVerbose: boolean; private _blockAndLogStreamerIfExists: BlockAndLogStreamer<Block, Log> | undefined; private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer; @@ -35,7 +34,6 @@ export class EventWatcher { ) { this._isVerbose = isVerbose; this._web3Wrapper = new Web3Wrapper(provider); - this._stateLayer = stateLayer; this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs) ? DEFAULT_EVENT_POLLING_INTERVAL_MS : pollingIntervalIfExistsMs; @@ -62,8 +60,8 @@ export class EventWatcher { throw new Error(OrderWatcherError.SubscriptionAlreadyPresent); } this._blockAndLogStreamerIfExists = new BlockAndLogStreamer( - this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper), - this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper), + this._blockstreamGetBlockOrNullAsync.bind(this), + this._blockstreamGetLogsAsync.bind(this), this._onBlockAndLogStreamerError.bind(this), ); const catchAllLogFilter = {}; @@ -82,6 +80,32 @@ export class EventWatcher { this._onLogStateChangedAsync.bind(this, callback, isRemoved), ); } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetBlockOrNullAsync(hash: string): Promise<Block | null> { + const shouldIncludeTransactionData = false; + const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync<Block | null>({ + method: 'eth_getBlockByHash', + params: [hash, shouldIncludeTransactionData], + }); + return blockOrNull; + } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetLatestBlockOrNullAsync(): Promise<Block | null> { + const shouldIncludeTransactionData = false; + const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync<Block | null>({ + method: 'eth_getBlockByNumber', + params: [BlockParamLiteral.Latest, shouldIncludeTransactionData], + }); + return blockOrNull; + } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetLogsAsync(filterOptions: FilterObject): Promise<RawLogEntry[]> { + const logs = await this._web3Wrapper.sendRawPayloadAsync<RawLogEntry[]>({ + method: 'eth_getLogs', + params: [filterOptions], + }); + return logs as RawLogEntry[]; + } private _stopBlockAndLogStream(): void { if (_.isUndefined(this._blockAndLogStreamerIfExists)) { throw new Error(OrderWatcherError.SubscriptionNotFound); @@ -95,16 +119,20 @@ export class EventWatcher { private async _onLogStateChangedAsync( callback: EventWatcherCallback, isRemoved: boolean, - log: LogEntry, + rawLog: RawLogEntry, ): Promise<void> { + const log: LogEntry = marshaller.unmarshalLog(rawLog); await this._emitDifferencesAsync(log, isRemoved ? LogEventState.Removed : LogEventState.Added, callback); } private async _reconcileBlockAsync(): Promise<void> { - const latestBlock = await this._web3Wrapper.getBlockAsync(this._stateLayer); + const latestBlockOrNull = await this._blockstreamGetLatestBlockOrNullAsync(); + if (_.isNull(latestBlockOrNull)) { + return; // noop + } // We need to coerce to Block type cause Web3.Block includes types for mempool blocks if (!_.isUndefined(this._blockAndLogStreamerIfExists)) { // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined - await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block); + await this._blockAndLogStreamerIfExists.reconcileNewBlock(latestBlockOrNull); } } private async _emitDifferencesAsync( diff --git a/packages/order-watcher/src/order_watcher/expiration_watcher.ts b/packages/order-watcher/src/order_watcher/expiration_watcher.ts index 6eadf14c7..ad20a6e3f 100644 --- a/packages/order-watcher/src/order_watcher/expiration_watcher.ts +++ b/packages/order-watcher/src/order_watcher/expiration_watcher.ts @@ -1,4 +1,4 @@ -import { BigNumber, intervalUtils } from '@0xproject/utils'; +import { BigNumber, intervalUtils } from '@0x/utils'; import { RBTree } from 'bintrees'; import * as _ from 'lodash'; diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index e2d6fc270..96c5ca7b4 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -1,5 +1,8 @@ // tslint:disable:no-unnecessary-type-assertion +import { ContractAddresses } from '@0x/contract-addresses'; +import * as artifacts from '@0x/contract-artifacts'; import { + AssetBalanceAndProxyAllowanceFetcher, ContractWrappers, ERC20TokenApprovalEventArgs, ERC20TokenEventArgs, @@ -15,27 +18,25 @@ import { ExchangeEventArgs, ExchangeEvents, ExchangeFillEventArgs, + OrderFilledCancelledFetcher, WETH9DepositEventArgs, WETH9EventArgs, WETH9Events, WETH9WithdrawalEventArgs, -} from '@0xproject/contract-wrappers'; -import { schemas } from '@0xproject/json-schemas'; +} from '@0x/contract-wrappers'; +import { schemas } from '@0x/json-schemas'; import { assetDataUtils, BalanceAndProxyAllowanceLazyStore, OrderFilledCancelledLazyStore, orderHashUtils, OrderStateUtils, -} from '@0xproject/order-utils'; -import { AssetProxyId, ExchangeContractErrs, OrderState, SignedOrder } from '@0xproject/types'; -import { errorUtils, intervalUtils } from '@0xproject/utils'; +} from '@0x/order-utils'; +import { AssetProxyId, ExchangeContractErrs, OrderState, SignedOrder, Stats } from '@0x/types'; +import { errorUtils, intervalUtils } from '@0x/utils'; import { BlockParamLiteral, LogEntryEvent, LogWithDecodedArgs, Provider } from 'ethereum-types'; import * as _ from 'lodash'; -import { artifacts } from '../artifacts'; -import { AssetBalanceAndProxyAllowanceFetcher } from '../fetchers/asset_balance_and_proxy_allowance_fetcher'; -import { OrderFilledCancelledFetcher } from '../fetchers/order_filled_cancelled_fetcher'; import { orderWatcherPartialConfigSchema } from '../schemas/order_watcher_partial_config_schema'; import { OnOrderStateChangeCallback, OrderWatcherConfig, OrderWatcherError } from '../types'; import { assert } from '../utils/assert'; @@ -87,9 +88,18 @@ export class OrderWatcher { private readonly _cleanupJobInterval: number; private _cleanupJobIntervalIdIfExists?: NodeJS.Timer; private _callbackIfExists?: OnOrderStateChangeCallback; + /** + * Instantiate a new OrderWatcher + * @param provider Web3 provider to use for JSON RPC calls + * @param networkId NetworkId to watch orders on + * @param contractAddresses Optional contract addresses. Defaults to known + * addresses based on networkId. + * @param partialConfig Optional configurations + */ constructor( provider: Provider, networkId: number, + contractAddresses?: ContractAddresses, partialConfig: Partial<OrderWatcherConfig> = DEFAULT_ORDER_WATCHER_CONFIG, ) { assert.isWeb3Provider('provider', provider); @@ -104,9 +114,14 @@ export class OrderWatcher { this._collisionResistantAbiDecoder = new CollisionResistanceAbiDecoder( artifacts.ERC20Token.compilerOutput.abi, artifacts.ERC721Token.compilerOutput.abi, - [artifacts.EtherToken.compilerOutput.abi, artifacts.Exchange.compilerOutput.abi], + [artifacts.WETH9.compilerOutput.abi, artifacts.Exchange.compilerOutput.abi], ); - const contractWrappers = new ContractWrappers(provider, { networkId }); + const contractWrappers = new ContractWrappers(provider, { + networkId, + // Note(albrow): We let the contract-wrappers package handle + // default values for contractAddresses. + contractAddresses, + }); this._eventWatcher = new EventWatcher(provider, config.eventPollingIntervalMs, STATE_LAYER, config.isVerbose); const balanceAndProxyAllowanceFetcher = new AssetBalanceAndProxyAllowanceFetcher( contractWrappers.erc20Token, @@ -207,6 +222,14 @@ export class OrderWatcher { this._expirationWatcher.unsubscribe(); intervalUtils.clearAsyncExcludingInterval(this._cleanupJobIntervalIdIfExists); } + /** + * Gets statistics of the OrderWatcher Instance. + */ + public getStats(): Stats { + return { + orderCount: _.size(this._orderByOrderHash), + }; + } private async _cleanupAsync(): Promise<void> { for (const orderHash of _.keys(this._orderByOrderHash)) { this._cleanupOrderRelatedState(orderHash); @@ -269,6 +292,7 @@ export class OrderWatcher { return; // noop } const decodedLog = (maybeDecodedLog as any) as LogWithDecodedArgs<ContractEventArgs>; + const transactionHash = decodedLog.transactionHash; switch (decodedLog.event) { case ERC20TokenEvents.Approval: case ERC721TokenEvents.Approval: { @@ -284,7 +308,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } else { // ERC721 @@ -297,7 +321,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } } @@ -316,7 +340,7 @@ export class OrderWatcher { args._from, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } else { // ERC721 @@ -330,7 +354,7 @@ export class OrderWatcher { args._from, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } } @@ -344,7 +368,7 @@ export class OrderWatcher { args._owner, tokenAddress, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } case WETH9Events.Deposit: { @@ -357,7 +381,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } case WETH9Events.Withdrawal: { @@ -370,7 +394,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } case ExchangeEvents.Fill: { @@ -381,7 +405,7 @@ export class OrderWatcher { const orderHash = args.orderHash; const isOrderWatched = !_.isUndefined(this._orderByOrderHash[orderHash]); if (isOrderWatched) { - await this._emitRevalidateOrdersAsync([orderHash]); + await this._emitRevalidateOrdersAsync([orderHash], transactionHash); } break; } @@ -393,7 +417,7 @@ export class OrderWatcher { const orderHash = args.orderHash; const isOrderWatched = !_.isUndefined(this._orderByOrderHash[orderHash]); if (isOrderWatched) { - await this._emitRevalidateOrdersAsync([orderHash]); + await this._emitRevalidateOrdersAsync([orderHash], transactionHash); } break; } @@ -404,7 +428,7 @@ export class OrderWatcher { this._orderFilledCancelledLazyStore.deleteAllIsCancelled(); // Revalidate orders const orderHashes = this._dependentOrderHashesTracker.getDependentOrderHashesByMaker(args.makerAddress); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } @@ -412,12 +436,12 @@ export class OrderWatcher { throw errorUtils.spawnSwitchErr('decodedLog.event', decodedLog.event); } } - private async _emitRevalidateOrdersAsync(orderHashes: string[]): Promise<void> { + private async _emitRevalidateOrdersAsync(orderHashes: string[], transactionHash?: string): Promise<void> { for (const orderHash of orderHashes) { const signedOrder = this._orderByOrderHash[orderHash]; // Most of these calls will never reach the network because the data is fetched from stores // and only updated when cache is invalidated - const orderState = await this._orderStateUtils.getOpenOrderStateAsync(signedOrder); + const orderState = await this._orderStateUtils.getOpenOrderStateAsync(signedOrder, transactionHash); if (_.isUndefined(this._callbackIfExists)) { break; // Unsubscribe was called } diff --git a/packages/order-watcher/src/types.ts b/packages/order-watcher/src/types.ts index 27d892985..8078dd971 100644 --- a/packages/order-watcher/src/types.ts +++ b/packages/order-watcher/src/types.ts @@ -1,4 +1,4 @@ -import { OrderState } from '@0xproject/types'; +import { OrderState } from '@0x/types'; import { LogEntryEvent } from 'ethereum-types'; export enum OrderWatcherError { diff --git a/packages/order-watcher/src/utils/assert.ts b/packages/order-watcher/src/utils/assert.ts index a891a60d2..ccfc7325c 100644 --- a/packages/order-watcher/src/utils/assert.ts +++ b/packages/order-watcher/src/utils/assert.ts @@ -1,13 +1,13 @@ -import { assert as sharedAssert } from '@0xproject/assert'; +import { assert as sharedAssert } from '@0x/assert'; // HACK: We need those two unused imports because they're actually used by sharedAssert which gets injected here // tslint:disable:no-unused-variable -import { Schema } from '@0xproject/json-schemas'; -import { ECSignature } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; +import { Schema } from '@0x/json-schemas'; +import { ECSignature } from '@0x/types'; +import { BigNumber } from '@0x/utils'; // tslint:enable:no-unused-variable import { Provider } from 'ethereum-types'; -import { isValidSignatureAsync } from '@0xproject/order-utils'; +import { signatureUtils } from '@0x/order-utils'; export const assert = { ...sharedAssert, @@ -17,7 +17,7 @@ export const assert = { signature: string, signerAddress: string, ): Promise<void> { - const isValid = await isValidSignatureAsync(provider, orderHash, signature, signerAddress); + const isValid = await signatureUtils.isValidSignatureAsync(provider, orderHash, signature, signerAddress); assert.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`); }, }; diff --git a/packages/order-watcher/src/utils/utils.ts b/packages/order-watcher/src/utils/utils.ts index 087fc635e..a7d10aaf9 100644 --- a/packages/order-watcher/src/utils/utils.ts +++ b/packages/order-watcher/src/utils/utils.ts @@ -1,4 +1,4 @@ -import { BigNumber } from '@0xproject/utils'; +import { BigNumber } from '@0x/utils'; export const utils = { getCurrentUnixTimestampSec(): BigNumber { diff --git a/packages/order-watcher/test/expiration_watcher_test.ts b/packages/order-watcher/test/expiration_watcher_test.ts index ea9923487..fb5ea2a27 100644 --- a/packages/order-watcher/test/expiration_watcher_test.ts +++ b/packages/order-watcher/test/expiration_watcher_test.ts @@ -1,10 +1,9 @@ -import { ContractWrappers } from '@0xproject/contract-wrappers'; -import { tokenUtils } from '@0xproject/contract-wrappers/lib/test/utils/token_utils'; -import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils'; -import { FillScenarios } from '@0xproject/fill-scenarios'; -import { assetDataUtils, orderHashUtils } from '@0xproject/order-utils'; -import { DoneCallback } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; +import { tokenUtils } from '@0x/contract-wrappers/lib/test/utils/token_utils'; +import { BlockchainLifecycle, callbackErrorReporter } from '@0x/dev-utils'; +import { FillScenarios } from '@0x/fill-scenarios'; +import { assetDataUtils, orderHashUtils } from '@0x/order-utils'; +import { DoneCallback } from '@0x/types'; +import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; import * as _ from 'lodash'; import 'mocha'; @@ -14,7 +13,7 @@ import { ExpirationWatcher } from '../src/order_watcher/expiration_watcher'; import { utils } from '../src/utils/utils'; import { chaiSetup } from './utils/chai_setup'; -import { constants } from './utils/constants'; +import { migrateOnceAsync } from './utils/migrate'; import { provider, web3Wrapper } from './utils/web3_wrapper'; chaiSetup.configure(); @@ -23,14 +22,8 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); const MILISECONDS_IN_SECOND = 1000; describe('ExpirationWatcher', () => { - const config = { - networkId: constants.TESTRPC_NETWORK_ID, - }; - const contractWrappers = new ContractWrappers(provider, config); let userAddresses: string[]; - let zrxTokenAddress: string; let fillScenarios: FillScenarios; - const exchangeContractAddress = contractWrappers.exchange.getContractAddress(); let makerAssetData: string; let takerAssetData: string; let coinbase: string; @@ -42,16 +35,16 @@ describe('ExpirationWatcher', () => { let timer: Sinon.SinonFakeTimers; let expirationWatcher: ExpirationWatcher; before(async () => { + const contractAddresses = await migrateOnceAsync(); await blockchainLifecycle.startAsync(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - zrxTokenAddress = tokenUtils.getProtocolTokenAddress(); fillScenarios = new FillScenarios( provider, userAddresses, - zrxTokenAddress, - exchangeContractAddress, - contractWrappers.erc20Proxy.getContractAddress(), - contractWrappers.erc721Proxy.getContractAddress(), + contractAddresses.zrxToken, + contractAddresses.exchange, + contractAddresses.erc20Proxy, + contractAddresses.erc721Proxy, ); [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses; const [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); diff --git a/packages/order-watcher/test/global_hooks.ts b/packages/order-watcher/test/global_hooks.ts index 99df04a51..26c37158f 100644 --- a/packages/order-watcher/test/global_hooks.ts +++ b/packages/order-watcher/test/global_hooks.ts @@ -1,17 +1,6 @@ -import { devConstants } from '@0xproject/dev-utils'; -import { runV2MigrationsAsync } from '@0xproject/migrations'; - -import { provider } from './utils/web3_wrapper'; - -before('migrate contracts', async function(): Promise<void> { +before('set up mocha', async function(): Promise<void> { // HACK: Since the migrations take longer then our global mocha timeout limit // we manually increase it for this before hook. const mochaTestTimeoutMs = 25000; this.timeout(mochaTestTimeoutMs); // tslint:disable-line:no-invalid-this - const txDefaults = { - gas: devConstants.GAS_LIMIT, - from: devConstants.TESTRPC_FIRST_ADDRESS, - }; - const artifactsDir = `src/artifacts`; - await runV2MigrationsAsync(provider, artifactsDir, txDefaults); }); diff --git a/packages/order-watcher/test/order_watcher_test.ts b/packages/order-watcher/test/order_watcher_test.ts index 38bfde7ef..271e5dec5 100644 --- a/packages/order-watcher/test/order_watcher_test.ts +++ b/packages/order-watcher/test/order_watcher_test.ts @@ -1,9 +1,9 @@ // tslint:disable:no-unnecessary-type-assertion -import { ContractWrappers } from '@0xproject/contract-wrappers'; -import { tokenUtils } from '@0xproject/contract-wrappers/lib/test/utils/token_utils'; -import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils'; -import { FillScenarios } from '@0xproject/fill-scenarios'; -import { assetDataUtils, orderHashUtils } from '@0xproject/order-utils'; +import { ContractWrappers } from '@0x/contract-wrappers'; +import { tokenUtils } from '@0x/contract-wrappers/lib/test/utils/token_utils'; +import { BlockchainLifecycle, callbackErrorReporter } from '@0x/dev-utils'; +import { FillScenarios } from '@0x/fill-scenarios'; +import { assetDataUtils, orderHashUtils } from '@0x/order-utils'; import { DoneCallback, ExchangeContractErrs, @@ -11,9 +11,9 @@ import { OrderStateInvalid, OrderStateValid, SignedOrder, -} from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +} from '@0x/types'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as chai from 'chai'; import * as _ from 'lodash'; import 'mocha'; @@ -27,6 +27,7 @@ import { OrderWatcherError } from '../src/types'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; +import { migrateOnceAsync } from './utils/migrate'; import { provider, web3Wrapper } from './utils/web3_wrapper'; const TIMEOUT_MS = 150; @@ -36,13 +37,10 @@ const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); describe('OrderWatcher', () => { - const networkId = constants.TESTRPC_NETWORK_ID; - const config = { networkId }; - const contractWrappers = new ContractWrappers(provider, config); + let contractWrappers: ContractWrappers; let fillScenarios: FillScenarios; let userAddresses: string[]; let zrxTokenAddress: string; - let exchangeContractAddress: string; let makerAssetData: string; let takerAssetData: string; let makerTokenAddress: string; @@ -56,17 +54,23 @@ describe('OrderWatcher', () => { const decimals = constants.ZRX_DECIMALS; const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals); before(async () => { + const contractAddresses = await migrateOnceAsync(); await blockchainLifecycle.startAsync(); + const networkId = constants.TESTRPC_NETWORK_ID; + const config = { + networkId, + contractAddresses, + }; + contractWrappers = new ContractWrappers(provider, config); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - zrxTokenAddress = tokenUtils.getProtocolTokenAddress(); - exchangeContractAddress = contractWrappers.exchange.getContractAddress(); + zrxTokenAddress = contractAddresses.zrxToken; fillScenarios = new FillScenarios( provider, userAddresses, zrxTokenAddress, - exchangeContractAddress, - contractWrappers.erc20Proxy.getContractAddress(), - contractWrappers.erc721Proxy.getContractAddress(), + contractAddresses.exchange, + contractAddresses.erc20Proxy, + contractAddresses.erc721Proxy, ); [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses; [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); @@ -75,7 +79,7 @@ describe('OrderWatcher', () => { assetDataUtils.encodeERC20AssetData(takerTokenAddress), ]; const orderWatcherConfig = {}; - orderWatcher = new OrderWatcher(provider, networkId, orderWatcherConfig); + orderWatcher = new OrderWatcher(provider, networkId, contractAddresses, orderWatcherConfig); }); after(async () => { await blockchainLifecycle.revertAsync(); @@ -140,6 +144,23 @@ describe('OrderWatcher', () => { expect(() => orderWatcher.subscribe(_.noop.bind(_))).to.throw(OrderWatcherError.SubscriptionAlreadyPresent); }); }); + describe('#getStats', async () => { + it('orderCount should increment and decrement with order additions and removals', async () => { + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableAmount, + ); + const orderHash = orderHashUtils.getOrderHashHex(signedOrder); + expect(orderWatcher.getStats().orderCount).to.be.eq(0); + await orderWatcher.addOrderAsync(signedOrder); + expect(orderWatcher.getStats().orderCount).to.be.eq(1); + orderWatcher.removeOrder(orderHash); + expect(orderWatcher.getStats().orderCount).to.be.eq(0); + }); + }); describe('tests with cleanup', async () => { afterEach(async () => { orderWatcher.unsubscribe(); @@ -250,6 +271,32 @@ describe('OrderWatcher', () => { await contractWrappers.exchange.fillOrderAsync(signedOrder, fillableAmount, takerAddress); })().catch(done); }); + it('should include transactionHash in emitted orderStateInvalid when watched order fully filled', (done: DoneCallback) => { + (async () => { + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableAmount, + ); + await orderWatcher.addOrderAsync(signedOrder); + + let transactionHash: string; + const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { + expect(orderState.isValid).to.be.false(); + const invalidOrderState = orderState as OrderStateInvalid; + expect(invalidOrderState.transactionHash).to.be.equal(transactionHash); + }); + orderWatcher.subscribe(callback); + + transactionHash = await contractWrappers.exchange.fillOrderAsync( + signedOrder, + fillableAmount, + takerAddress, + ); + })().catch(done); + }); it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( diff --git a/packages/order-watcher/test/utils/migrate.ts b/packages/order-watcher/test/utils/migrate.ts new file mode 100644 index 000000000..665ce0faa --- /dev/null +++ b/packages/order-watcher/test/utils/migrate.ts @@ -0,0 +1,18 @@ +import { ContractAddresses } from '@0x/contract-addresses'; +import { devConstants } from '@0x/dev-utils'; +import { runMigrationsOnceAsync } from '@0x/migrations'; + +import { provider } from './web3_wrapper'; + +/** + * Configures and runs the migrations exactly once. Any subsequent times this is + * called, it returns the cached addresses. + * @returns The addresses of contracts that were deployed during the migrations. + */ +export async function migrateOnceAsync(): Promise<ContractAddresses> { + const txDefaults = { + gas: devConstants.GAS_LIMIT, + from: devConstants.TESTRPC_FIRST_ADDRESS, + }; + return runMigrationsOnceAsync(provider, txDefaults); +} diff --git a/packages/order-watcher/test/utils/token_utils.ts b/packages/order-watcher/test/utils/token_utils.ts deleted file mode 100644 index f91b3797f..000000000 --- a/packages/order-watcher/test/utils/token_utils.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Token } from '@0xproject/types'; -import * as _ from 'lodash'; - -import { InternalOrderWatcherError } from '../../src/types'; - -const PROTOCOL_TOKEN_SYMBOL = 'ZRX'; -const WETH_TOKEN_SYMBOL = 'WETH'; - -export class TokenUtils { - private readonly _tokens: Token[]; - constructor(tokens: Token[]) { - this._tokens = tokens; - } - public getProtocolTokenOrThrow(): Token { - const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL }); - if (_.isUndefined(zrxToken)) { - throw new Error(InternalOrderWatcherError.ZrxNotInTokenRegistry); - } - return zrxToken; - } - public getWethTokenOrThrow(): Token { - const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL }); - if (_.isUndefined(wethToken)) { - throw new Error(InternalOrderWatcherError.WethNotInTokenRegistry); - } - return wethToken; - } - public getDummyTokens(): Token[] { - const dummyTokens = _.filter(this._tokens, token => { - return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol); - }); - return dummyTokens; - } -} diff --git a/packages/order-watcher/test/utils/web3_wrapper.ts b/packages/order-watcher/test/utils/web3_wrapper.ts index ab801fa7f..accfcb7fe 100644 --- a/packages/order-watcher/test/utils/web3_wrapper.ts +++ b/packages/order-watcher/test/utils/web3_wrapper.ts @@ -1,5 +1,5 @@ -import { web3Factory } from '@0xproject/dev-utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { web3Factory } from '@0x/dev-utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { Provider } from 'ethereum-types'; const provider: Provider = web3Factory.getRpcProvider({ shouldUseInProcessGanache: true }); diff --git a/packages/order-watcher/tsconfig.json b/packages/order-watcher/tsconfig.json index e35816553..2ee711adc 100644 --- a/packages/order-watcher/tsconfig.json +++ b/packages/order-watcher/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig", "compilerOptions": { - "outDir": "lib" + "outDir": "lib", + "rootDir": "." }, "include": ["./src/**/*", "./test/**/*"] } diff --git a/packages/order-watcher/tslint.json b/packages/order-watcher/tslint.json index 059573ce7..4ade3b924 100644 --- a/packages/order-watcher/tslint.json +++ b/packages/order-watcher/tslint.json @@ -2,5 +2,5 @@ "rules": { "prefer-readonly": true }, - "extends": ["@0xproject/tslint-config"] + "extends": ["@0x/tslint-config"] } diff --git a/packages/order-watcher/typedoc-tsconfig.json b/packages/order-watcher/typedoc-tsconfig.json new file mode 100644 index 000000000..c9b0af1ae --- /dev/null +++ b/packages/order-watcher/typedoc-tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../typedoc-tsconfig", + "compilerOptions": { + "outDir": "lib" + }, + "include": ["./src/**/*", "./test/**/*"] +} |