diff options
author | Fabio Berger <me@fabioberger.com> | 2018-07-19 23:48:06 +0800 |
---|---|---|
committer | Fabio Berger <me@fabioberger.com> | 2018-07-19 23:48:06 +0800 |
commit | d8898cf9a30cc349868afcf2b78e6369e57aa726 (patch) | |
tree | f96d1aa76c7e5aa9e3311d5cdbd0d31c8ec8d7fb /packages/contract-wrappers/src | |
parent | 1aaf633df883f62fad890b2d87a2dc89067821c5 (diff) | |
parent | 3de88d5345c7a4549bc69e2ca28f0601f5d42189 (diff) | |
download | dexon-0x-contracts-d8898cf9a30cc349868afcf2b78e6369e57aa726.tar dexon-0x-contracts-d8898cf9a30cc349868afcf2b78e6369e57aa726.tar.gz dexon-0x-contracts-d8898cf9a30cc349868afcf2b78e6369e57aa726.tar.bz2 dexon-0x-contracts-d8898cf9a30cc349868afcf2b78e6369e57aa726.tar.lz dexon-0x-contracts-d8898cf9a30cc349868afcf2b78e6369e57aa726.tar.xz dexon-0x-contracts-d8898cf9a30cc349868afcf2b78e6369e57aa726.tar.zst dexon-0x-contracts-d8898cf9a30cc349868afcf2b78e6369e57aa726.zip |
merge v2-prototype
Diffstat (limited to 'packages/contract-wrappers/src')
9 files changed, 64 insertions, 39 deletions
diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts index b8ca4d29b..daf70253a 100644 --- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts @@ -1,5 +1,5 @@ import { ContractArtifact } from '@0xproject/sol-compiler'; -import { AbiDecoder, intervalUtils } from '@0xproject/utils'; +import { AbiDecoder, intervalUtils, logUtils } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { BlockParamLiteral, ContractAbi, FilterObject, LogEntry, LogWithDecodedArgs, RawLog } from 'ethereum-types'; import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream'; @@ -41,6 +41,13 @@ export abstract class ContractWrapper { }; private _onLogAddedSubscriptionToken: string | undefined; private _onLogRemovedSubscriptionToken: string | undefined; + private static _onBlockAndLogStreamerError(isVerbose: boolean, err: Error): void { + // Since Blockstream errors are all recoverable, we simply log them if the verbose + // config is passed in. + if (isVerbose) { + logUtils.warn(err); + } + } constructor(web3Wrapper: Web3Wrapper, networkId: number, blockPollingIntervalMs?: number) { this._web3Wrapper = web3Wrapper; this._networkId = networkId; @@ -79,10 +86,11 @@ export abstract class ContractWrapper { indexFilterValues: IndexedFilterValues, abi: ContractAbi, callback: EventCallback<ArgsType>, + isVerbose: boolean = false, ): string { const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi); if (_.isUndefined(this._blockAndLogStreamerIfExists)) { - this._startBlockAndLogStream(); + this._startBlockAndLogStream(isVerbose); } const filterToken = filterUtils.generateUUID(); this._filters[filterToken] = filter; @@ -151,21 +159,21 @@ export abstract class ContractWrapper { } }); } - private _startBlockAndLogStream(): void { + private _startBlockAndLogStream(isVerbose: boolean): void { if (!_.isUndefined(this._blockAndLogStreamerIfExists)) { throw new Error(ContractWrappersError.SubscriptionAlreadyPresent); } this._blockAndLogStreamerIfExists = new BlockAndLogStreamer( this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper), this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper), - this._onBlockAndLogStreamerError.bind(this), + ContractWrapper._onBlockAndLogStreamerError.bind(this, isVerbose), ); const catchAllLogFilter = {}; this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter); this._blockAndLogStreamIntervalIfExists = intervalUtils.setAsyncExcludingInterval( this._reconcileBlockAsync.bind(this), this._blockPollingIntervalMs, - this._onReconcileBlockError.bind(this), + ContractWrapper._onBlockAndLogStreamerError.bind(this, isVerbose), ); let isRemoved = false; this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded( @@ -176,20 +184,10 @@ 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 => { - this._unsubscribe(filterToken, err); - }); - } + // HACK: This should be a package-scoped method (which doesn't exist in TS) + // We don't want this method available in the public interface for all classes + // who inherit from ContractWrapper, and it is only used by the internal implementation + // of those higher classes. // tslint:disable-next-line:no-unused-variable private _setNetworkId(networkId: number): void { this._networkId = networkId; diff --git a/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts index 29c63564e..17bda5085 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts @@ -347,6 +347,7 @@ export class ERC20TokenWrapper extends ContractWrapper { * @param indexFilterValues An object where the keys are indexed args returned by the event and * the value is the value you are interested in. E.g `{maker: aUserAddressHex}` * @param callback Callback that gets called when a log is added/removed + * @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered) * @return Subscription token used later to unsubscribe */ public subscribe<ArgsType extends ERC20TokenEventArgs>( @@ -354,6 +355,7 @@ export class ERC20TokenWrapper extends ContractWrapper { eventName: ERC20TokenEvents, indexFilterValues: IndexedFilterValues, callback: EventCallback<ArgsType>, + isVerbose: boolean = false, ): string { assert.isETHAddressHex('tokenAddress', tokenAddress); assert.doesBelongToStringEnum('eventName', eventName, ERC20TokenEvents); @@ -366,6 +368,7 @@ export class ERC20TokenWrapper extends ContractWrapper { indexFilterValues, artifacts.ERC20Token.compilerOutput.abi, callback, + isVerbose, ); return subscriptionToken; } diff --git a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts index b7e5519c4..7c2b41c62 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts @@ -342,15 +342,17 @@ export class ERC721TokenWrapper extends ContractWrapper { const normalizedSenderAddress = senderAddress.toLowerCase(); const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); const ownerAddress = await this.getOwnerOfAsync(tokenAddress, tokenId); - const isApprovedForAll = await this.isApprovedForAllAsync( - normalizedTokenAddress, - ownerAddress, - normalizedSenderAddress, - ); - if (!isApprovedForAll) { - const approvedAddress = await this.getApprovedIfExistsAsync(normalizedTokenAddress, tokenId); - if (approvedAddress !== senderAddress) { - throw new Error(ContractWrappersError.ERC721NoApproval); + if (normalizedSenderAddress !== ownerAddress) { + const isApprovedForAll = await this.isApprovedForAllAsync( + normalizedTokenAddress, + ownerAddress, + normalizedSenderAddress, + ); + if (!isApprovedForAll) { + const approvedAddress = await this.getApprovedIfExistsAsync(normalizedTokenAddress, tokenId); + if (approvedAddress !== normalizedSenderAddress) { + throw new Error(ContractWrappersError.ERC721NoApproval); + } } } const txHash = await tokenContract.transferFrom.sendTransactionAsync( @@ -372,6 +374,7 @@ export class ERC721TokenWrapper extends ContractWrapper { * @param indexFilterValues An object where the keys are indexed args returned by the event and * the value is the value you are interested in. E.g `{maker: aUserAddressHex}` * @param callback Callback that gets called when a log is added/removed + * @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered) * @return Subscription token used later to unsubscribe */ public subscribe<ArgsType extends ERC721TokenEventArgs>( @@ -379,6 +382,7 @@ export class ERC721TokenWrapper extends ContractWrapper { eventName: ERC721TokenEvents, indexFilterValues: IndexedFilterValues, callback: EventCallback<ArgsType>, + isVerbose: boolean = false, ): string { assert.isETHAddressHex('tokenAddress', tokenAddress); assert.doesBelongToStringEnum('eventName', eventName, ERC721TokenEvents); @@ -391,6 +395,7 @@ export class ERC721TokenWrapper extends ContractWrapper { indexFilterValues, artifacts.ERC721Token.compilerOutput.abi, callback, + isVerbose, ); return subscriptionToken; } diff --git a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts index 01440a5e1..5046d3667 100644 --- a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts @@ -146,6 +146,7 @@ export class EtherTokenWrapper extends ContractWrapper { * @param indexFilterValues An object where the keys are indexed args returned by the event and * the value is the value you are interested in. E.g `{_owner: aUserAddressHex}` * @param callback Callback that gets called when a log is added/removed + * @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered) * @return Subscription token used later to unsubscribe */ public subscribe<ArgsType extends WETH9EventArgs>( @@ -153,6 +154,7 @@ export class EtherTokenWrapper extends ContractWrapper { eventName: WETH9Events, indexFilterValues: IndexedFilterValues, callback: EventCallback<ArgsType>, + isVerbose: boolean = false, ): string { assert.isETHAddressHex('etherTokenAddress', etherTokenAddress); const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); @@ -165,6 +167,7 @@ export class EtherTokenWrapper extends ContractWrapper { indexFilterValues, artifacts.EtherToken.compilerOutput.abi, callback, + isVerbose, ); return subscriptionToken; } diff --git a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts index 8b7148aed..3e7619228 100644 --- a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts @@ -1,4 +1,5 @@ import { schemas } from '@0xproject/json-schemas'; +import { assetDataUtils } from '@0xproject/order-utils'; import { AssetProxyId, Order, SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; @@ -988,12 +989,14 @@ export class ExchangeWrapper extends ContractWrapper { * @param indexFilterValues An object where the keys are indexed args returned by the event and * the value is the value you are interested in. E.g `{maker: aUserAddressHex}` * @param callback Callback that gets called when a log is added/removed + * @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered) * @return Subscription token used later to unsubscribe */ public subscribe<ArgsType extends ExchangeEventArgs>( eventName: ExchangeEvents, indexFilterValues: IndexedFilterValues, callback: EventCallback<ArgsType>, + isVerbose: boolean = false, ): string { assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); @@ -1005,6 +1008,7 @@ export class ExchangeWrapper extends ContractWrapper { indexFilterValues, artifacts.Exchange.compilerOutput.abi, callback, + isVerbose, ); return subscriptionToken; } @@ -1068,9 +1072,9 @@ export class ExchangeWrapper extends ContractWrapper { * Returns the ZRX asset data used by the exchange contract. * @return ZRX asset data */ - public async getZRXAssetDataAsync(): Promise<string> { - const exchangeInstance = await this._getExchangeContractAsync(); - const zrxAssetData = exchangeInstance.ZRX_ASSET_DATA.callAsync(); + public getZRXAssetData(): string { + const zrxTokenAddress = this.getZRXTokenAddress(); + const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxTokenAddress); return zrxAssetData; } // tslint:disable:no-unused-variable diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index b3c4b2c60..e5485d7a6 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -1,7 +1,10 @@ export { ContractWrappers } from './contract_wrappers'; export { ERC20TokenWrapper } from './contract_wrappers/erc20_token_wrapper'; +export { ERC721TokenWrapper } from './contract_wrappers/erc721_token_wrapper'; export { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper'; +export { ExchangeWrapper } from './contract_wrappers/exchange_wrapper'; export { ERC20ProxyWrapper } from './contract_wrappers/erc20_proxy_wrapper'; +export { ERC721ProxyWrapper } from './contract_wrappers/erc721_proxy_wrapper'; export { ContractWrappersError, @@ -23,7 +26,15 @@ export { OrderInfo, } from './types'; -export { Order, SignedOrder, ECSignature, OrderStateValid, OrderStateInvalid, OrderState } from '@0xproject/types'; +export { + Order, + SignedOrder, + ECSignature, + OrderStateValid, + OrderStateInvalid, + OrderState, + AssetProxyId, +} from '@0xproject/types'; export { BlockParamLiteral, @@ -57,6 +68,7 @@ export { ERC721TokenApprovalForAllEventArgs, ERC721TokenTransferEventArgs, ERC721TokenEvents, + ERC721TokenEventArgs, } from './contract_wrappers/generated/erc721_token'; export { diff --git a/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts b/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts index 4b68daf1a..7e2eca61c 100644 --- a/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts +++ b/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts @@ -8,8 +8,8 @@ export const contractWrappersPrivateNetworkConfigSchema = { gasPrice: { $ref: '/Number' }, zrxContractAddress: { $ref: '/Address' }, exchangeContractAddress: { $ref: '/Address' }, - tokenRegistryContractAddress: { $ref: '/Address' }, - tokenTransferProxyContractAddress: { $ref: '/Address' }, + erc20ProxyContractAddress: { $ref: '/Address' }, + erc721ProxyContractAddress: { $ref: '/Address' }, blockPollingIntervalMs: { type: 'number' }, orderWatcherConfig: { type: 'object', @@ -30,7 +30,7 @@ export const contractWrappersPrivateNetworkConfigSchema = { 'networkId', 'zrxContractAddress', 'exchangeContractAddress', - 'tokenRegistryContractAddress', - 'tokenTransferProxyContractAddress', + 'erc20ProxyContractAddress', + 'erc721ProxyContractAddress', ], }; diff --git a/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts b/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts index 988872376..b80e04310 100644 --- a/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts +++ b/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts @@ -22,8 +22,8 @@ export const contractWrappersPublicNetworkConfigSchema = { gasPrice: { $ref: '/Number' }, zrxContractAddress: { $ref: '/Address' }, exchangeContractAddress: { $ref: '/Address' }, - tokenRegistryContractAddress: { $ref: '/Address' }, - tokenTransferProxyContractAddress: { $ref: '/Address' }, + erc20ProxyContractAddress: { $ref: '/Address' }, + erc721ProxyContractAddress: { $ref: '/Address' }, blockPollingIntervalMs: { type: 'number' }, orderWatcherConfig: { type: 'object', diff --git a/packages/contract-wrappers/src/utils/assert.ts b/packages/contract-wrappers/src/utils/assert.ts index da6697b08..842b16fa0 100644 --- a/packages/contract-wrappers/src/utils/assert.ts +++ b/packages/contract-wrappers/src/utils/assert.ts @@ -1,5 +1,5 @@ import { assert as sharedAssert } from '@0xproject/assert'; -// We need those two unused imports because they're actually used by sharedAssert which gets injected here +// HACK: We need those two unused imports because they're actually used by sharedAssert which gets injected here import { Schema } from '@0xproject/json-schemas'; // tslint:disable-line:no-unused-variable import { isValidSignatureAsync } from '@0xproject/order-utils'; import { ECSignature } from '@0xproject/types'; // tslint:disable-line:no-unused-variable |