diff options
author | Leonid Logvinov <logvinov.leon@gmail.com> | 2017-08-28 22:47:49 +0800 |
---|---|---|
committer | Leonid Logvinov <logvinov.leon@gmail.com> | 2017-08-28 22:49:57 +0800 |
commit | 96da2c26dceca03340a213baae5a490df2f7183c (patch) | |
tree | 6c984b77c1cd5ca312310d7f72ad4b512ecb9df5 | |
parent | 0afc95982b195378653e15697f65d4ad3bf48e66 (diff) | |
download | dexon-sol-tools-96da2c26dceca03340a213baae5a490df2f7183c.tar dexon-sol-tools-96da2c26dceca03340a213baae5a490df2f7183c.tar.gz dexon-sol-tools-96da2c26dceca03340a213baae5a490df2f7183c.tar.bz2 dexon-sol-tools-96da2c26dceca03340a213baae5a490df2f7183c.tar.lz dexon-sol-tools-96da2c26dceca03340a213baae5a490df2f7183c.tar.xz dexon-sol-tools-96da2c26dceca03340a213baae5a490df2f7183c.tar.zst dexon-sol-tools-96da2c26dceca03340a213baae5a490df2f7183c.zip |
Use 0x-json-schemas
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/0x.ts | 11 | ||||
-rw-r--r-- | src/contract_wrappers/exchange_wrapper.ts | 43 | ||||
-rw-r--r-- | src/contract_wrappers/token_wrapper.ts | 7 | ||||
-rw-r--r-- | src/globals.d.ts | 49 | ||||
-rw-r--r-- | src/schemas/basic_type_schemas.ts | 11 | ||||
-rw-r--r-- | src/schemas/ec_signature_schema.ts | 20 | ||||
-rw-r--r-- | src/schemas/index_filter_values_schema.ts | 11 | ||||
-rw-r--r-- | src/schemas/order_cancel_schema.ts | 12 | ||||
-rw-r--r-- | src/schemas/order_fill_or_kill_requests_schema.ts | 12 | ||||
-rw-r--r-- | src/schemas/order_fill_requests_schema.ts | 12 | ||||
-rw-r--r-- | src/schemas/order_hash_schema.ts | 5 | ||||
-rw-r--r-- | src/schemas/order_schemas.ts | 39 | ||||
-rw-r--r-- | src/schemas/signed_orders_schema.ts | 5 | ||||
-rw-r--r-- | src/schemas/subscription_opts_schema.ts | 20 | ||||
-rw-r--r-- | src/schemas/token_schema.ts | 11 | ||||
-rw-r--r-- | src/utils/assert.ts | 2 | ||||
-rw-r--r-- | src/utils/schema_validator.ts | 36 | ||||
-rw-r--r-- | test/schema_test.ts | 354 | ||||
-rw-r--r-- | test/token_registry_wrapper_test.ts | 10 | ||||
-rw-r--r-- | yarn.lock | 12 |
21 files changed, 40 insertions, 644 deletions
diff --git a/package.json b/package.json index 75b691989..173c24c26 100644 --- a/package.json +++ b/package.json @@ -90,13 +90,13 @@ "webpack": "^3.1.0" }, "dependencies": { + "0x-json-schemas": "^0.1.5", "bignumber.js": "^4.0.2", "compare-versions": "^3.0.1", "es6-promisify": "^5.0.0", "ethereumjs-abi": "^0.6.4", "ethereumjs-util": "^5.1.1", "find-versions": "^2.0.0", - "jsonschema": "^1.1.1", "lodash": "^4.17.4", "publish-release": "^1.3.3", "truffle-contract": "^2.0.1", @@ -1,5 +1,6 @@ import * as _ from 'lodash'; import * as BigNumber from 'bignumber.js'; +import {SchemaValidator, schemas} from '0x-json-schemas'; import {bigNumberConfigs} from './bignumber_config'; import * as ethUtil from 'ethereumjs-util'; import contract = require('truffle-contract'); @@ -13,13 +14,9 @@ import {assert} from './utils/assert'; import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper'; import {TokenRegistryWrapper} from './contract_wrappers/token_registry_wrapper'; import {EtherTokenWrapper} from './contract_wrappers/ether_token_wrapper'; -import {ecSignatureSchema} from './schemas/ec_signature_schema'; import {TokenWrapper} from './contract_wrappers/token_wrapper'; import {TokenTransferProxyWrapper} from './contract_wrappers/token_transfer_proxy_wrapper'; import {ECSignature, ZeroExError, Order, SignedOrder, Web3Provider} from './types'; -import {orderHashSchema} from './schemas/order_hash_schema'; -import {orderSchema} from './schemas/order_schemas'; -import {SchemaValidator} from './utils/schema_validator'; // Customize our BigNumber instances bigNumberConfigs.configure(); @@ -70,7 +67,7 @@ export class ZeroEx { */ public static isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean { assert.isHexString('data', data); - assert.doesConformToSchema('signature', signature, ecSignatureSchema); + assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema); assert.isETHAddressHex('signerAddress', signerAddress); const dataBuff = ethUtil.toBuffer(data); @@ -113,7 +110,7 @@ export class ZeroEx { // format, we only assert that we were indeed passed a string. assert.isString('orderHash', orderHash); const schemaValidator = new SchemaValidator(); - const isValidOrderHash = schemaValidator.validate(orderHash, orderHashSchema).valid; + const isValidOrderHash = schemaValidator.validate(orderHash, schemas.orderHashSchema).valid; return isValidOrderHash; } /** @@ -154,7 +151,7 @@ export class ZeroEx { * @return The resulting orderHash from hashing the supplied order. */ public static getOrderHashHex(order: Order|SignedOrder): string { - assert.doesConformToSchema('order', order, orderSchema); + assert.doesConformToSchema('order', order, schemas.orderSchema); const orderHashHex = utils.getOrderHashHex(order); return orderHashHex; } diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 66cf06dee..a01940f4b 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -1,5 +1,6 @@ import * as _ from 'lodash'; import * as BigNumber from 'bignumber.js'; +import {SchemaValidator, schemas} from '0x-json-schemas'; import promisify = require('es6-promisify'); import {Web3Wrapper} from '../web3_wrapper'; import { @@ -32,15 +33,6 @@ import {utils} from '../utils/utils'; import {eventUtils} from '../utils/event_utils'; import {OrderValidationUtils} from '../utils/order_validation_utils'; import {ContractWrapper} from './contract_wrapper'; -import {ecSignatureSchema} from '../schemas/ec_signature_schema'; -import {signedOrdersSchema} from '../schemas/signed_orders_schema'; -import {subscriptionOptsSchema} from '../schemas/subscription_opts_schema'; -import {indexFilterValuesSchema} from '../schemas/index_filter_values_schema'; -import {orderFillRequestsSchema} from '../schemas/order_fill_requests_schema'; -import {orderCancellationRequestsSchema} from '../schemas/order_cancel_schema'; -import {orderFillOrKillRequestsSchema} from '../schemas/order_fill_or_kill_requests_schema'; -import {orderHashSchema} from '../schemas/order_hash_schema'; -import {signedOrderSchema, orderSchema} from '../schemas/order_schemas'; import {constants} from '../utils/constants'; import {TokenWrapper} from './token_wrapper'; import {decorators} from '../utils/decorators'; @@ -96,7 +88,7 @@ export class ExchangeWrapper extends ContractWrapper { * @return The amount of the order (in taker tokens) that has either been filled or canceled. */ public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber.BigNumber> { - assert.doesConformToSchema('orderHash', orderHash, orderHashSchema); + assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); const exchangeContract = await this._getExchangeContractAsync(); let unavailableTakerTokenAmount = await exchangeContract.getUnavailableTakerTokenAmount.call(orderHash); @@ -110,7 +102,7 @@ export class ExchangeWrapper extends ContractWrapper { * @return The amount of the order (in taker tokens) that has already been filled. */ public async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber.BigNumber> { - assert.doesConformToSchema('orderHash', orderHash, orderHashSchema); + assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); const exchangeContract = await this._getExchangeContractAsync(); let fillAmountInBaseUnits = await exchangeContract.filled.call(orderHash); @@ -125,7 +117,7 @@ export class ExchangeWrapper extends ContractWrapper { * @return The amount of the order (in taker tokens) that has been cancelled. */ public async getCanceledTakerAmountAsync(orderHash: string): Promise<BigNumber.BigNumber> { - assert.doesConformToSchema('orderHash', orderHash, orderHashSchema); + assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); const exchangeContract = await this._getExchangeContractAsync(); let cancelledAmountInBaseUnits = await exchangeContract.cancelled.call(orderHash); @@ -155,7 +147,7 @@ export class ExchangeWrapper extends ContractWrapper { public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber.BigNumber, shouldThrowOnInsufficientBalanceOrAllowance: boolean, takerAddress: string): Promise<BigNumber.BigNumber> { - assert.doesConformToSchema('signedOrder', signedOrder, signedOrderSchema); + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isBigNumber('fillTakerTokenAmount', fillTakerTokenAmount); assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); @@ -215,7 +207,7 @@ export class ExchangeWrapper extends ContractWrapper { public async fillOrdersUpToAsync(signedOrders: SignedOrder[], fillTakerTokenAmount: BigNumber.BigNumber, shouldThrowOnInsufficientBalanceOrAllowance: boolean, takerAddress: string): Promise<BigNumber.BigNumber> { - assert.doesConformToSchema('signedOrders', signedOrders, signedOrdersSchema); + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); const takerTokenAddresses = _.map(signedOrders, signedOrder => signedOrder.takerTokenAddress); assert.hasAtMostOneUniqueValue(takerTokenAddresses, ExchangeContractErrs.MultipleTakerTokensInFillUpToDisallowed); @@ -301,7 +293,7 @@ export class ExchangeWrapper extends ContractWrapper { public async batchFillOrdersAsync(orderFillRequests: OrderFillRequest[], shouldThrowOnInsufficientBalanceOrAllowance: boolean, takerAddress: string): Promise<void> { - assert.doesConformToSchema('orderFillRequests', orderFillRequests, orderFillRequestsSchema); + assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema); const exchangeContractAddresses = _.map( orderFillRequests, orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress, @@ -372,7 +364,7 @@ export class ExchangeWrapper extends ContractWrapper { @decorators.contractCallErrorHandler public async fillOrKillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber.BigNumber, takerAddress: string): Promise<void> { - assert.doesConformToSchema('signedOrder', signedOrder, signedOrderSchema); + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isBigNumber('fillTakerTokenAmount', fillTakerTokenAmount); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); @@ -417,7 +409,8 @@ export class ExchangeWrapper extends ContractWrapper { @decorators.contractCallErrorHandler public async batchFillOrKillAsync(orderFillOrKillRequests: OrderFillOrKillRequest[], takerAddress: string): Promise<void> { - assert.doesConformToSchema('orderFillOrKillRequests', orderFillOrKillRequests, orderFillOrKillRequestsSchema); + assert.doesConformToSchema('orderFillOrKillRequests', orderFillOrKillRequests, + schemas.orderFillOrKillRequestsSchema); const exchangeContractAddresses = _.map( orderFillOrKillRequests, orderFillOrKillRequest => orderFillOrKillRequest.signedOrder.exchangeContractAddress, @@ -483,7 +476,7 @@ export class ExchangeWrapper extends ContractWrapper { @decorators.contractCallErrorHandler public async cancelOrderAsync( order: Order|SignedOrder, cancelTakerTokenAmount: BigNumber.BigNumber): Promise<BigNumber.BigNumber> { - assert.doesConformToSchema('order', order, orderSchema); + assert.doesConformToSchema('order', order, schemas.orderSchema); assert.isBigNumber('takerTokenCancelAmount', cancelTakerTokenAmount); await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper); @@ -522,7 +515,7 @@ export class ExchangeWrapper extends ContractWrapper { @decorators.contractCallErrorHandler public async batchCancelOrdersAsync(orderCancellationRequests: OrderCancellationRequest[]): Promise<void> { assert.doesConformToSchema('orderCancellationRequests', orderCancellationRequests, - orderCancellationRequestsSchema); + schemas.orderCancellationRequestsSchema); const exchangeContractAddresses = _.map( orderCancellationRequests, orderCancellationRequest => orderCancellationRequest.order.exchangeContractAddress, @@ -584,8 +577,8 @@ export class ExchangeWrapper extends ContractWrapper { Promise<ContractEventEmitter> { assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress); assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents); - assert.doesConformToSchema('subscriptionOpts', subscriptionOpts, subscriptionOptsSchema); - assert.doesConformToSchema('indexFilterValues', indexFilterValues, indexFilterValuesSchema); + assert.doesConformToSchema('subscriptionOpts', subscriptionOpts, schemas.subscriptionOptsSchema); + assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); const exchangeContract = await this._getExchangeContractAsync(); let createLogEvent: CreateContractEvent; switch (eventName) { @@ -637,7 +630,7 @@ export class ExchangeWrapper extends ContractWrapper { public async validateFillOrderThrowIfInvalidAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber.BigNumber, takerAddress: string): Promise<void> { - assert.doesConformToSchema('signedOrder', signedOrder, signedOrderSchema); + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isBigNumber('fillTakerTokenAmount', fillTakerTokenAmount); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); const zrxTokenAddress = await this._getZRXTokenAddressAsync(); @@ -652,7 +645,7 @@ export class ExchangeWrapper extends ContractWrapper { */ public async validateCancelOrderThrowIfInvalidAsync( order: Order, cancelTakerTokenAmount: BigNumber.BigNumber): Promise<void> { - assert.doesConformToSchema('order', order, orderSchema); + assert.doesConformToSchema('order', order, schemas.orderSchema); assert.isBigNumber('cancelTakerTokenAmount', cancelTakerTokenAmount); const orderHash = utils.getOrderHashHex(order); const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash); @@ -670,7 +663,7 @@ export class ExchangeWrapper extends ContractWrapper { public async validateFillOrKillOrderThrowIfInvalidAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber.BigNumber, takerAddress: string): Promise<void> { - assert.doesConformToSchema('signedOrder', signedOrder, signedOrderSchema); + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isBigNumber('fillTakerTokenAmount', fillTakerTokenAmount); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); const zrxTokenAddress = await this._getZRXTokenAddressAsync(); @@ -705,7 +698,7 @@ export class ExchangeWrapper extends ContractWrapper { private async _isValidSignatureUsingContractCallAsync(dataHex: string, ecSignature: ECSignature, signerAddressHex: string): Promise<boolean> { assert.isHexString('dataHex', dataHex); - assert.doesConformToSchema('ecSignature', ecSignature, ecSignatureSchema); + assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema); assert.isETHAddressHex('signerAddressHex', signerAddressHex); const exchangeInstance = await this._getExchangeContractAsync(); diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts index a2812ccdb..51490359e 100644 --- a/src/contract_wrappers/token_wrapper.ts +++ b/src/contract_wrappers/token_wrapper.ts @@ -1,5 +1,6 @@ import * as _ from 'lodash'; import * as BigNumber from 'bignumber.js'; +import {SchemaValidator, schemas} from '0x-json-schemas'; import {Web3Wrapper} from '../web3_wrapper'; import {assert} from '../utils/assert'; import {utils} from '../utils/utils'; @@ -8,8 +9,6 @@ import {constants} from '../utils/constants'; import {ContractWrapper} from './contract_wrapper'; import * as TokenArtifacts from '../artifacts/Token.json'; import * as TokenTransferProxyArtifacts from '../artifacts/TokenTransferProxy.json'; -import {subscriptionOptsSchema} from '../schemas/subscription_opts_schema'; -import {indexFilterValuesSchema} from '../schemas/index_filter_values_schema'; import { TokenContract, ZeroExError, @@ -230,8 +229,8 @@ export class TokenWrapper extends ContractWrapper { indexFilterValues: IndexedFilterValues): Promise<ContractEventEmitter> { assert.isETHAddressHex('tokenAddress', tokenAddress); assert.doesBelongToStringEnum('eventName', eventName, TokenEvents); - assert.doesConformToSchema('subscriptionOpts', subscriptionOpts, subscriptionOptsSchema); - assert.doesConformToSchema('indexFilterValues', indexFilterValues, indexFilterValuesSchema); + assert.doesConformToSchema('subscriptionOpts', subscriptionOpts, schemas.subscriptionOptsSchema); + assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); const tokenContract = await this._getTokenContractAsync(tokenAddress); let createLogEvent: CreateContractEvent; switch (eventName) { diff --git a/src/globals.d.ts b/src/globals.d.ts index f1720e366..9879a57ad 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -25,55 +25,6 @@ declare namespace Chai { } /* tslint:enable */ -// jsonschema declarations -// Source: https://github.com/tdegrunt/jsonschema/blob/master/lib/index.d.ts -declare interface Schema { - id?: string; - $schema?: string; - title?: string; - description?: string; - multipleOf?: number; - maximum?: number; - exclusiveMaximum?: boolean; - minimum?: number; - exclusiveMinimum?: boolean; - maxLength?: number; - minLength?: number; - pattern?: string; - additionalItems?: boolean | Schema; - items?: Schema | Schema[]; - maxItems?: number; - minItems?: number; - uniqueItems?: boolean; - maxProperties?: number; - minProperties?: number; - required?: string[]; - additionalProperties?: boolean | Schema; - definitions?: { - [name: string]: Schema; - }; - properties?: { - [name: string]: Schema; - }; - patternProperties?: { - [name: string]: Schema; - }; - dependencies?: { - [name: string]: Schema | string[]; - }; - 'enum'?: any[]; - type?: string | string[]; - allOf?: Schema[]; - anyOf?: Schema[]; - oneOf?: Schema[]; - not?: Schema; - // This is the only property that's not defined in https://github.com/tdegrunt/jsonschema/blob/master/lib/index.d.ts - // There is an open issue for that: https://github.com/tdegrunt/jsonschema/issues/194 - // There is also an opened PR: https://github.com/tdegrunt/jsonschema/pull/218/files - // As soon as it gets merged we should be good to use types from 'jsonschema' package - $ref?: string; -} - declare module '*.json' { const json: any; /* tslint:disable */ diff --git a/src/schemas/basic_type_schemas.ts b/src/schemas/basic_type_schemas.ts deleted file mode 100644 index 5d66cf79b..000000000 --- a/src/schemas/basic_type_schemas.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const addressSchema = { - id: '/addressSchema', - type: 'string', - pattern: '^0x[0-9a-f]{40}$', -}; - -export const numberSchema = { - id: '/numberSchema', - type: 'string', - pattern: '^\\d+(\\.\\d+)?$', -}; diff --git a/src/schemas/ec_signature_schema.ts b/src/schemas/ec_signature_schema.ts deleted file mode 100644 index df1121989..000000000 --- a/src/schemas/ec_signature_schema.ts +++ /dev/null @@ -1,20 +0,0 @@ -export const ecSignatureParameterSchema = { - id: '/ecSignatureParameter', - type: 'string', - pattern: '^0[xX][0-9A-Fa-f]{64}$', -}; - -export const ecSignatureSchema = { - id: '/ECSignature', - properties: { - v: { - type: 'number', - minimum: 27, - maximum: 28, - }, - r: {$ref: '/ecSignatureParameter'}, - s: {$ref: '/ecSignatureParameter'}, - }, - required: ['v', 'r', 's'], - type: 'object', -}; diff --git a/src/schemas/index_filter_values_schema.ts b/src/schemas/index_filter_values_schema.ts deleted file mode 100644 index 7c8d3f943..000000000 --- a/src/schemas/index_filter_values_schema.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const indexFilterValuesSchema = { - id: '/indexFilterValues', - additionalProperties: { - oneOf: [ - {$ref: '/numberSchema'}, - {$ref: '/addressSchema'}, - {$ref: '/orderHashSchema'}, - ], - }, - type: 'object', -}; diff --git a/src/schemas/order_cancel_schema.ts b/src/schemas/order_cancel_schema.ts deleted file mode 100644 index 04b2c179f..000000000 --- a/src/schemas/order_cancel_schema.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const orderCancellationRequestsSchema = { - id: '/OrderCancellationRequests', - type: 'array', - items: { - properties: { - order: {$ref: '/orderSchema'}, - takerTokenCancelAmount: {$ref: '/numberSchema'}, - }, - required: ['order', 'takerTokenCancelAmount'], - type: 'object', - }, -}; diff --git a/src/schemas/order_fill_or_kill_requests_schema.ts b/src/schemas/order_fill_or_kill_requests_schema.ts deleted file mode 100644 index 6f7878c45..000000000 --- a/src/schemas/order_fill_or_kill_requests_schema.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const orderFillOrKillRequestsSchema = { - id: '/OrderFillOrKillRequests', - type: 'array', - items: { - properties: { - signedOrder: {$ref: '/signedOrderSchema'}, - fillTakerAmount: {$ref: '/numberSchema'}, - }, - required: ['signedOrder', 'fillTakerAmount'], - type: 'object', - }, -}; diff --git a/src/schemas/order_fill_requests_schema.ts b/src/schemas/order_fill_requests_schema.ts deleted file mode 100644 index 0f3ee1e99..000000000 --- a/src/schemas/order_fill_requests_schema.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const orderFillRequestsSchema = { - id: '/OrderFillRequests', - type: 'array', - items: { - properties: { - signedOrder: {$ref: '/signedOrderSchema'}, - takerTokenFillAmount: {$ref: '/numberSchema'}, - }, - required: ['signedOrder', 'takerTokenFillAmount'], - type: 'object', - }, -}; diff --git a/src/schemas/order_hash_schema.ts b/src/schemas/order_hash_schema.ts deleted file mode 100644 index 9773a88f9..000000000 --- a/src/schemas/order_hash_schema.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const orderHashSchema = { - id: '/orderHashSchema', - type: 'string', - pattern: '^0x[0-9a-fA-F]{64}$', -}; diff --git a/src/schemas/order_schemas.ts b/src/schemas/order_schemas.ts deleted file mode 100644 index c346687b5..000000000 --- a/src/schemas/order_schemas.ts +++ /dev/null @@ -1,39 +0,0 @@ -export const orderSchema = { - id: '/orderSchema', - properties: { - maker: {$ref: '/addressSchema'}, - taker: {$ref: '/addressSchema'}, - - makerFee: {$ref: '/numberSchema'}, - takerFee: {$ref: '/numberSchema'}, - - makerTokenAmount: {$ref: '/numberSchema'}, - takerTokenAmount: {$ref: '/numberSchema'}, - - makerTokenAddress: {$ref: '/addressSchema'}, - takerTokenAddress: {$ref: '/addressSchema'}, - - salt: {$ref: '/numberSchema'}, - feeRecipient: {$ref: '/addressSchema'}, - expirationUnixTimestampSec: {$ref: '/numberSchema'}, - exchangeContractAddress: {$ref: '/addressSchema'}, - }, - required: [ - 'maker', 'taker', 'makerFee', 'takerFee', 'makerTokenAmount', 'takerTokenAmount', - 'salt', 'feeRecipient', 'expirationUnixTimestampSec', 'exchangeContractAddress', - ], - type: 'object', -}; - -export const signedOrderSchema = { - id: '/signedOrderSchema', - allOf: [ - { $ref: '/orderSchema' }, - { - properties: { - ecSignature: {$ref: '/ECSignature'}, - }, - required: ['ecSignature'], - }, - ], -}; diff --git a/src/schemas/signed_orders_schema.ts b/src/schemas/signed_orders_schema.ts deleted file mode 100644 index 3b3b23649..000000000 --- a/src/schemas/signed_orders_schema.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const signedOrdersSchema = { - id: '/signedOrdersSchema', - type: 'array', - items: {$ref: '/signedOrderSchema'}, -}; diff --git a/src/schemas/subscription_opts_schema.ts b/src/schemas/subscription_opts_schema.ts deleted file mode 100644 index 0bb44fecf..000000000 --- a/src/schemas/subscription_opts_schema.ts +++ /dev/null @@ -1,20 +0,0 @@ -export const blockParamSchema = { - id: '/blockParam', - oneOf: [ - { - type: 'number', - }, - { - enum: ['latest', 'earliest', 'pending'], - }, - ], -}; - -export const subscriptionOptsSchema = { - id: '/subscriptionOpts', - properties: { - fromBlock: {$ref: '/blockParam'}, - toBlock: {$ref: '/blockParam'}, - }, - type: 'object', -}; diff --git a/src/schemas/token_schema.ts b/src/schemas/token_schema.ts deleted file mode 100644 index e9e359fdf..000000000 --- a/src/schemas/token_schema.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const tokenSchema = { - id: '/token', - properties: { - name: {type: 'string'}, - symbol: {type: 'string'}, - decimals: {type: 'number'}, - address: {$ref: '/addressSchema'}, - }, - required: ['name', 'symbol', 'decimals', 'address'], - type: 'object', -}; diff --git a/src/utils/assert.ts b/src/utils/assert.ts index 0e6169b44..a26b19311 100644 --- a/src/utils/assert.ts +++ b/src/utils/assert.ts @@ -2,7 +2,7 @@ import * as _ from 'lodash'; import * as BigNumber from 'bignumber.js'; import * as Web3 from 'web3'; import {Web3Wrapper} from '../web3_wrapper'; -import {SchemaValidator} from './schema_validator'; +import {SchemaValidator, Schema} from '0x-json-schemas'; const HEX_REGEX = /^0x[0-9A-F]*$/i; diff --git a/src/utils/schema_validator.ts b/src/utils/schema_validator.ts deleted file mode 100644 index 6916aa85b..000000000 --- a/src/utils/schema_validator.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {Validator, ValidatorResult, Schema as JSONSchema} from 'jsonschema'; -import {ecSignatureSchema, ecSignatureParameterSchema} from '../schemas/ec_signature_schema'; -import {orderHashSchema} from '../schemas/order_hash_schema'; -import {orderSchema, signedOrderSchema} from '../schemas/order_schemas'; -import {addressSchema, numberSchema} from '../schemas/basic_type_schemas'; -import {tokenSchema} from '../schemas/token_schema'; -import {subscriptionOptsSchema, blockParamSchema} from '../schemas/subscription_opts_schema'; -import {indexFilterValuesSchema} from '../schemas/index_filter_values_schema'; -import {orderFillOrKillRequestsSchema} from '../schemas/order_fill_or_kill_requests_schema'; - -export class SchemaValidator { - private validator: Validator; - constructor() { - this.validator = new Validator(); - this.validator.addSchema(tokenSchema as JSONSchema, tokenSchema.id); - this.validator.addSchema(orderSchema as JSONSchema, orderSchema.id); - this.validator.addSchema(numberSchema as JSONSchema, numberSchema.id); - this.validator.addSchema(addressSchema as JSONSchema, addressSchema.id); - this.validator.addSchema(orderHashSchema as JSONSchema, orderHashSchema.id); - this.validator.addSchema(blockParamSchema as JSONSchema, blockParamSchema.id); - this.validator.addSchema(ecSignatureSchema as JSONSchema, ecSignatureSchema.id); - this.validator.addSchema(signedOrderSchema as JSONSchema, signedOrderSchema.id); - this.validator.addSchema(subscriptionOptsSchema as JSONSchema, subscriptionOptsSchema.id); - this.validator.addSchema(indexFilterValuesSchema as JSONSchema, indexFilterValuesSchema.id); - this.validator.addSchema(ecSignatureParameterSchema as JSONSchema, ecSignatureParameterSchema.id); - this.validator.addSchema(orderFillOrKillRequestsSchema as JSONSchema, orderFillOrKillRequestsSchema.id); - } - // In order to validate a complex JS object using jsonschema, we must replace any complex - // sub-types (e.g BigNumber) with a simpler string representation. Since BigNumber and other - // complex types implement the `toString` method, we can stringify the object and - // then parse it. The resultant object can then be checked using jsonschema. - public validate(instance: any, schema: Schema): ValidatorResult { - const jsonSchemaCompatibleObject = JSON.parse(JSON.stringify(instance)); - return this.validator.validate(jsonSchemaCompatibleObject, schema); - } -} diff --git a/test/schema_test.ts b/test/schema_test.ts deleted file mode 100644 index e47f8b8e5..000000000 --- a/test/schema_test.ts +++ /dev/null @@ -1,354 +0,0 @@ -import 'mocha'; -import * as _ from 'lodash'; -import * as chai from 'chai'; -import * as BigNumber from 'bignumber.js'; -import promisify = require('es6-promisify'); -import {constants} from './utils/constants'; -import {SchemaValidator} from '../src/utils/schema_validator'; -import {tokenSchema} from '../src/schemas/token_schema'; -import {orderHashSchema} from '../src/schemas/order_hash_schema'; -import {orderSchema, signedOrderSchema} from '../src/schemas/order_schemas'; -import {addressSchema, numberSchema} from '../src/schemas/basic_type_schemas'; -import {orderFillOrKillRequestsSchema} from '../src/schemas/order_fill_or_kill_requests_schema'; -import {ecSignatureParameterSchema, ecSignatureSchema} from '../src/schemas/ec_signature_schema'; -import {orderCancellationRequestsSchema} from '../src/schemas/order_cancel_schema'; -import {orderFillRequestsSchema} from '../src/schemas/order_fill_requests_schema'; -import {blockParamSchema, subscriptionOptsSchema} from '../src/schemas/subscription_opts_schema'; - -chai.config.includeStack = true; -const expect = chai.expect; - -describe('Schema', () => { - const validator = new SchemaValidator(); - const validateAgainstSchema = (testCases: any[], schema: any, shouldFail = false) => { - _.forEach(testCases, (testCase: any) => { - if (shouldFail) { - expect(validator.validate(testCase, schema).errors).to.be.lengthOf.at.least(1); - } else { - expect(validator.validate(testCase, schema).errors).to.be.lengthOf(0); - } - }); - }; - describe('#numberSchema', () => { - it('should validate valid numbers', () => { - const testCases = ['42', '0', '1.3', '0.2', '00.00']; - validateAgainstSchema(testCases, numberSchema); - }); - it('should fail for invalid numbers', () => { - const testCases = ['.3', '1.', 'abacaba', 'и', '1..0']; - const shouldFail = true; - validateAgainstSchema(testCases, numberSchema, shouldFail); - }); - }); - describe('#addressSchema', () => { - it('should validate valid addresses', () => { - const testCases = ['0x8b0292b11a196601ed2ce54b665cafeca0347d42', constants.NULL_ADDRESS]; - validateAgainstSchema(testCases, addressSchema); - }); - it('should fail for invalid addresses', () => { - const testCases = [ - '0x', - '0', - '0x00', - '0xzzzzzzB11a196601eD2ce54B665CaFEca0347D42', - '0x8b0292B11a196601eD2ce54B665CaFEca0347D42', - ]; - const shouldFail = true; - validateAgainstSchema(testCases, addressSchema, shouldFail); - }); - }); - describe('#ecSignatureParameterSchema', () => { - it('should validate valid parameters', () => { - const testCases = [ - '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33', - '0X40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', - ]; - validateAgainstSchema(testCases, ecSignatureParameterSchema); - }); - it('should fail for invalid parameters', () => { - const testCases = [ - '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3', // shorter - '0xzzzz9190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', // invalid characters - '40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', // no 0x - ]; - const shouldFail = true; - validateAgainstSchema(testCases, ecSignatureParameterSchema, shouldFail); - }); - }); - describe('#ecSignatureSchema', () => { - it('should validate valid signature', () => { - const signature = { - v: 27, - r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33', - s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', - }; - const testCases = [ - signature, - { - ...signature, - v: 28, - }, - ]; - validateAgainstSchema(testCases, ecSignatureSchema); - }); - it('should fail for invalid signature', () => { - const v = 27; - const r = '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33'; - const s = '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254'; - const testCases = [ - {}, - {v}, - {r, s, v: 31}, - ]; - const shouldFail = true; - validateAgainstSchema(testCases, ecSignatureSchema, shouldFail); - }); - }); - describe('#orderHashSchema', () => { - it('should validate valid order hash', () => { - const testCases = [ - '0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33', - '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', - ]; - validateAgainstSchema(testCases, orderHashSchema); - }); - it('should fail for invalid order hash', () => { - const testCases = [ - {}, - '0x', - '0x8b0292B11a196601eD2ce54B665CaFEca0347D42', - '61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33', - ]; - const shouldFail = true; - validateAgainstSchema(testCases, orderHashSchema, shouldFail); - }); - }); - describe('#blockParamSchema', () => { - it('should validate valid block param', () => { - const testCases = [ - 42, - 'latest', - 'pending', - 'earliest', - ]; - validateAgainstSchema(testCases, blockParamSchema); - }); - it('should fail for invalid block param', () => { - const testCases = [ - {}, - '42', - 'pemding', - ]; - const shouldFail = true; - validateAgainstSchema(testCases, blockParamSchema, shouldFail); - }); - }); - describe('#subscriptionOptsSchema', () => { - it('should validate valid subscription opts', () => { - const testCases = [ - {fromBlock: 42, toBlock: 'latest'}, - {fromBlock: 42}, - {}, - ]; - validateAgainstSchema(testCases, subscriptionOptsSchema); - }); - it('should fail for invalid subscription opts', () => { - const testCases = [ - {fromBlock: '42'}, - ]; - const shouldFail = true; - validateAgainstSchema(testCases, subscriptionOptsSchema, shouldFail); - }); - }); - describe('#tokenSchema', () => { - const token = { - name: 'Zero Ex', - symbol: 'ZRX', - decimals: 100500, - address: '0x8b0292b11a196601ed2ce54b665cafeca0347d42', - url: 'https://0xproject.com', - }; - it('should validate valid token', () => { - const testCases = [ - token, - ]; - validateAgainstSchema(testCases, tokenSchema); - }); - it('should fail for invalid token', () => { - const testCases = [ - { - ...token, - address: null, - }, - { - ...token, - decimals: undefined, - }, - [], - 4, - ]; - const shouldFail = true; - validateAgainstSchema(testCases, tokenSchema, shouldFail); - }); - }); - describe('order including schemas', () => { - const order = { - maker: constants.NULL_ADDRESS, - taker: constants.NULL_ADDRESS, - makerFee: '1', - takerFee: '2', - makerTokenAmount: '1', - takerTokenAmount: '2', - makerTokenAddress: constants.NULL_ADDRESS, - takerTokenAddress: constants.NULL_ADDRESS, - salt: '256', - feeRecipient: constants.NULL_ADDRESS, - exchangeContractAddress: constants.NULL_ADDRESS, - expirationUnixTimestampSec: '42', - }; - describe('#orderSchema', () => { - it('should validate valid order', () => { - const testCases = [ - order, - ]; - validateAgainstSchema(testCases, orderSchema); - }); - it('should fail for invalid order', () => { - const testCases = [ - { - ...order, - salt: undefined, - }, - { - ...order, - salt: 'salt', - }, - 'order', - ]; - const shouldFail = true; - validateAgainstSchema(testCases, orderSchema, shouldFail); - }); - }); - describe('signed order including schemas', () => { - const signedOrder = { - ...order, - ecSignature: { - v: 27, - r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33', - s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', - }, - }; - describe('#signedOrderSchema', () => { - it('should validate valid signed order', () => { - const testCases = [ - signedOrder, - ]; - validateAgainstSchema(testCases, signedOrderSchema); - }); - it('should fail for invalid signed order', () => { - const testCases = [ - { - ...signedOrder, - ecSignature: undefined, - }, - ]; - const shouldFail = true; - validateAgainstSchema(testCases, signedOrderSchema, shouldFail); - }); - }); - describe('#orderFillOrKillRequestsSchema', () => { - const orderFillOrKillRequests = [ - { - signedOrder, - fillTakerAmount: '5', - }, - ]; - it('should validate valid order fill or kill requests', () => { - const testCases = [ - orderFillOrKillRequests, - ]; - validateAgainstSchema(testCases, orderFillOrKillRequestsSchema); - }); - it('should fail for invalid order fill or kill requests', () => { - const testCases = [ - [ - { - ...orderFillOrKillRequests[0], - fillTakerAmount: undefined, - }, - ], - ]; - const shouldFail = true; - validateAgainstSchema(testCases, orderFillOrKillRequestsSchema, shouldFail); - }); - }); - describe('#orderCancellationRequestsSchema', () => { - const orderCancellationRequests = [ - { - order, - takerTokenCancelAmount: '5', - }, - ]; - it('should validate valid order cancellation requests', () => { - const testCases = [ - orderCancellationRequests, - ]; - validateAgainstSchema(testCases, orderCancellationRequestsSchema); - }); - it('should fail for invalid order cancellation requests', () => { - const testCases = [ - [ - { - ...orderCancellationRequests[0], - takerTokenCancelAmount: undefined, - }, - ], - ]; - const shouldFail = true; - validateAgainstSchema(testCases, orderCancellationRequestsSchema, shouldFail); - }); - }); - describe('#orderFillRequestsSchema', () => { - const orderFillRequests = [ - { - signedOrder, - takerTokenFillAmount: '5', - }, - ]; - it('should validate valid order fill requests', () => { - const testCases = [ - orderFillRequests, - ]; - validateAgainstSchema(testCases, orderFillRequestsSchema); - }); - it('should fail for invalid order fill requests', () => { - const testCases = [ - [ - { - ...orderFillRequests[0], - takerTokenFillAmount: undefined, - }, - ], - ]; - const shouldFail = true; - validateAgainstSchema(testCases, orderFillRequestsSchema, shouldFail); - }); - }); - }); - }); - describe('BigNumber serialization', () => { - it('should correctly serialize BigNumbers', () => { - const testCases = { - '42': '42', - '0': '0', - '1.3': '1.3', - '0.2': '0.2', - '00.00': '0', - '.3': '0.3', - }; - _.forEach(testCases, (serialized: string, input: string) => { - expect(JSON.parse(JSON.stringify(new BigNumber(input)))).to.be.equal(serialized); - }); - }); - }); -}); diff --git a/test/token_registry_wrapper_test.ts b/test/token_registry_wrapper_test.ts index e1702cd45..6b5dd517e 100644 --- a/test/token_registry_wrapper_test.ts +++ b/test/token_registry_wrapper_test.ts @@ -1,13 +1,11 @@ import * as _ from 'lodash'; import 'mocha'; import * as chai from 'chai'; +import {SchemaValidator, schemas} from '0x-json-schemas'; import {chaiSetup} from './utils/chai_setup'; import {web3Factory} from './utils/web3_factory'; import {ZeroEx, Token} from '../src'; import {BlockchainLifecycle} from './utils/blockchain_lifecycle'; -import {SchemaValidator} from '../src/utils/schema_validator'; -import {tokenSchema} from '../src/schemas/token_schema'; -import {addressSchema} from '../src/schemas/basic_type_schemas'; chaiSetup.configure(); const expect = chai.expect; @@ -49,7 +47,7 @@ describe('TokenRegistryWrapper', () => { const schemaValidator = new SchemaValidator(); _.each(tokens, token => { - const validationResult = schemaValidator.validate(token, tokenSchema); + const validationResult = schemaValidator.validate(token, schemas.tokenSchema); expect(validationResult.errors).to.have.lengthOf(0); }); }); @@ -61,7 +59,7 @@ describe('TokenRegistryWrapper', () => { const schemaValidator = new SchemaValidator(); _.each(tokenAddresses, tokenAddress => { - const validationResult = schemaValidator.validate(tokenAddress, addressSchema); + const validationResult = schemaValidator.validate(tokenAddress, schemas.addressSchema); expect(validationResult.errors).to.have.lengthOf(0); expect(tokenAddress).to.not.be.equal(ZeroEx.NULL_ADDRESS); }); @@ -113,7 +111,7 @@ describe('TokenRegistryWrapper', () => { const token = await zeroEx.tokenRegistry.getTokenIfExistsAsync(aToken.address); const schemaValidator = new SchemaValidator(); - const validationResult = schemaValidator.validate(token, tokenSchema); + const validationResult = schemaValidator.validate(token, schemas.tokenSchema); expect(validationResult.errors).to.have.lengthOf(0); }); it('should return return undefined when passed a token address not in the tokenRegistry', async () => { @@ -2,6 +2,12 @@ # yarn lockfile v1 +"0x-json-schemas@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/0x-json-schemas/-/0x-json-schemas-0.1.5.tgz#e114128ceefe33a0bc3981ec35af6780dec971c1" + dependencies: + jsonschema "^1.2.0" + "@types/bignumber.js@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-4.0.2.tgz#22a16946c9faa9f2c9c0ad4c7c3734a3033320ae" @@ -2746,9 +2752,9 @@ jsonpointer@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" -jsonschema@*, jsonschema@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.1.1.tgz#3cede8e3e411d377872eefbc9fdf26383cbc3ed9" +jsonschema@*, jsonschema@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.0.tgz#d6ebaf70798db7b3a20c544f6c9ef9319b077de2" jsprim@^1.2.2: version "1.4.0" |