aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sun <ffstudios1@gmail.com>2019-02-08 10:06:43 +0800
committerGitHub <noreply@github.com>2019-02-08 10:06:43 +0800
commitffd8349889cb27613364a423f1b0f5b87bb26099 (patch)
tree3eed4d2bee80083be39f6a930a8e6bf79572d8e8
parent1170cf18964f67cec41d380a4fff66735dca04a5 (diff)
parentf3716fd813952396aafed7e8bb92e6b4d63ecb7e (diff)
downloaddexon-0x-contracts-ffd8349889cb27613364a423f1b0f5b87bb26099.tar
dexon-0x-contracts-ffd8349889cb27613364a423f1b0f5b87bb26099.tar.gz
dexon-0x-contracts-ffd8349889cb27613364a423f1b0f5b87bb26099.tar.bz2
dexon-0x-contracts-ffd8349889cb27613364a423f1b0f5b87bb26099.tar.lz
dexon-0x-contracts-ffd8349889cb27613364a423f1b0f5b87bb26099.tar.xz
dexon-0x-contracts-ffd8349889cb27613364a423f1b0f5b87bb26099.tar.zst
dexon-0x-contracts-ffd8349889cb27613364a423f1b0f5b87bb26099.zip
Merge pull request #1581 from dave4506/feature/instant/bignumber-coerce-type
Big number input to Instant coercion to version utilized by 0x packages
-rw-r--r--packages/instant/src/index.umd.ts19
-rw-r--r--packages/instant/src/util/maybe_big_number.ts11
-rw-r--r--packages/instant/src/util/order_coercion.ts42
-rw-r--r--packages/instant/test/util/maybe_big_number.test.ts65
-rw-r--r--packages/instant/test/util/order_coercion.test.ts103
5 files changed, 235 insertions, 5 deletions
diff --git a/packages/instant/src/index.umd.ts b/packages/instant/src/index.umd.ts
index 0acf3f2ad..243bb569b 100644
--- a/packages/instant/src/index.umd.ts
+++ b/packages/instant/src/index.umd.ts
@@ -17,6 +17,7 @@ import { ZeroExInstantOverlay, ZeroExInstantOverlayProps } from './index';
import { Network, OrderSource } from './types';
import { analytics } from './util/analytics';
import { assert } from './util/assert';
+import { orderCoercionUtil } from './util/order_coercion';
import { providerFactory } from './util/provider_factory';
import { util } from './util/util';
@@ -93,16 +94,24 @@ export interface ZeroExInstantConfig extends ZeroExInstantOverlayProps {
}
export const render = (config: ZeroExInstantConfig, selector: string = DEFAULT_ZERO_EX_CONTAINER_SELECTOR) => {
- validateInstantRenderConfig(config, selector);
- if (config.shouldDisablePushToHistory) {
+ // Coerces BigNumber provided in config to version utilized by 0x packages
+ const coercedConfig = _.assign({}, config, {
+ orderSource: _.isArray(config.orderSource)
+ ? orderCoercionUtil.coerceOrderArrayFieldsToBigNumber(config.orderSource)
+ : config.orderSource,
+ });
+
+ validateInstantRenderConfig(coercedConfig, selector);
+
+ if (coercedConfig.shouldDisablePushToHistory) {
if (!isInstantRendered()) {
- renderInstant(config, selector);
+ renderInstant(coercedConfig, selector);
}
return;
}
// Before we render, push to history saying that instant is showing for this part of the history.
window.history.pushState({ zeroExInstantShowing: true }, '0x Instant');
- let removeInstant = renderInstant(config, selector);
+ let removeInstant = renderInstant(coercedConfig, selector);
// If the integrator defined a popstate handler, save it to __zeroExInstantIntegratorsPopStateHandler
// unless we have already done so on a previous render.
const anyWindow = window as any;
@@ -116,7 +125,7 @@ export const render = (config: ZeroExInstantConfig, selector: string = DEFAULT_Z
if (newState && newState.zeroExInstantShowing) {
// We have returned to a history state that expects instant to be rendered.
if (!isInstantRendered()) {
- removeInstant = renderInstant(config, selector);
+ removeInstant = renderInstant(coercedConfig, selector);
}
} else {
// History has changed to a different state.
diff --git a/packages/instant/src/util/maybe_big_number.ts b/packages/instant/src/util/maybe_big_number.ts
index f48473389..95fbd8695 100644
--- a/packages/instant/src/util/maybe_big_number.ts
+++ b/packages/instant/src/util/maybe_big_number.ts
@@ -22,4 +22,15 @@ export const maybeBigNumberUtil = {
}
return _.isUndefined(val1) && _.isUndefined(val2);
},
+ // converts a BigNumber or String to the BigNumber used by 0x libraries
+ toMaybeBigNumber: (value: any): Maybe<BigNumber> => {
+ if (_.isString(value)) {
+ return maybeBigNumberUtil.stringToMaybeBigNumber(value);
+ }
+ // checks for pre v8 bignumber with member variable
+ if (BigNumber.isBigNumber(value) || value.isBigNumber) {
+ return new BigNumber(value.toString());
+ }
+ return undefined;
+ },
};
diff --git a/packages/instant/src/util/order_coercion.ts b/packages/instant/src/util/order_coercion.ts
new file mode 100644
index 000000000..a1b468baf
--- /dev/null
+++ b/packages/instant/src/util/order_coercion.ts
@@ -0,0 +1,42 @@
+import { BigNumber } from '@0x/utils';
+import * as _ from 'lodash';
+
+import { maybeBigNumberUtil } from './maybe_big_number';
+
+const coerceBigNumberOrString = (value: any): BigNumber => {
+ const bn = maybeBigNumberUtil.toMaybeBigNumber(value);
+ return !!bn ? bn : value;
+};
+
+// function implies that the signed order already has been validated
+export const orderCoercionUtil = {
+ // coerces order big number values to the BigNumber version utilized by 0x
+ coerceFieldsToBigNumbers(obj: any, fields: string[]): any {
+ const result = _.assign({}, obj);
+ _.each(fields, field => {
+ _.update(result, field, (value: string) => {
+ if (_.isUndefined(value)) {
+ throw new Error(`Could not find field '${field}' while converting fields to BigNumber.`);
+ }
+ return coerceBigNumberOrString(value);
+ });
+ });
+ return result;
+ },
+
+ coerceOrderFieldsToBigNumber: (order: any): any => {
+ return orderCoercionUtil.coerceFieldsToBigNumbers(order, [
+ 'makerFee',
+ 'takerFee',
+ 'makerAssetAmount',
+ 'takerAssetAmount',
+ 'salt',
+ 'expirationTimeSeconds',
+ ]);
+ },
+ coerceOrderArrayFieldsToBigNumber: (orders: any[]): any[] => {
+ return _.map(orders, (value: any) => {
+ return orderCoercionUtil.coerceOrderFieldsToBigNumber(value);
+ });
+ },
+};
diff --git a/packages/instant/test/util/maybe_big_number.test.ts b/packages/instant/test/util/maybe_big_number.test.ts
new file mode 100644
index 000000000..508e8aaf0
--- /dev/null
+++ b/packages/instant/test/util/maybe_big_number.test.ts
@@ -0,0 +1,65 @@
+import { BigNumber } from '@0x/utils';
+
+import { maybeBigNumberUtil } from '../../src/util/maybe_big_number';
+
+const BIG_NUMBER_1 = new BigNumber('10.1');
+const BIG_NUMBER_2 = new BigNumber('10.1');
+const BIG_NUMBER_3 = new BigNumber('11.1');
+
+describe('maybeBigNumberUtil', () => {
+ describe('stringToMaybeBigNumber', () => {
+ it('should return undefined if stringValue is NaN', () => {
+ expect(maybeBigNumberUtil.stringToMaybeBigNumber('NaN')).toEqual(undefined);
+ });
+ it('should return bignumber constructed with stringValue', () => {
+ const bn = maybeBigNumberUtil.stringToMaybeBigNumber('10.1');
+ if (!!bn) {
+ expect(bn.toString()).toEqual('10.1');
+ }
+ });
+ it('should return undefined if stringValue is not valid (i.e not numeric)', () => {
+ expect(maybeBigNumberUtil.stringToMaybeBigNumber('test')).toEqual(undefined);
+ });
+ });
+
+ describe('areMaybeBigNumbersEqual', () => {
+ it('should return true if val1 and val2 are equivalent BigNumber values', () => {
+ expect(maybeBigNumberUtil.areMaybeBigNumbersEqual(BIG_NUMBER_1, BIG_NUMBER_2)).toEqual(true);
+ });
+ it('should return true if val1 and val2 are both undefined', () => {
+ expect(maybeBigNumberUtil.areMaybeBigNumbersEqual(undefined, undefined)).toEqual(true);
+ });
+ it('should return false if either one val1 or val2 is undefined', () => {
+ expect(maybeBigNumberUtil.areMaybeBigNumbersEqual(BIG_NUMBER_1, undefined)).toEqual(false);
+ });
+ it('should return false if val1 and val2 are equivalent values BigNumber', () => {
+ expect(maybeBigNumberUtil.areMaybeBigNumbersEqual(BIG_NUMBER_1, BIG_NUMBER_3)).toEqual(false);
+ });
+ });
+
+ // this doesn't test coercing a pre v8.0.0 version of big number to desired version
+ describe('toMaybeBigNumber', () => {
+ it('should return BigNumber (>=v8.0.0) constructed with value if type is string', () => {
+ const bn = maybeBigNumberUtil.toMaybeBigNumber('10.1');
+ if (!!bn) {
+ expect(bn.toString()).toEqual('10.1');
+ }
+ });
+ it('should return undefined if value is NaN', () => {
+ expect(maybeBigNumberUtil.toMaybeBigNumber('NaN')).toEqual(undefined);
+ });
+ it('should return undefined if value as string is not valid (i.e not numeric)', () => {
+ expect(maybeBigNumberUtil.toMaybeBigNumber('test')).toEqual(undefined);
+ });
+ it('should return undefined if value as string is not valid (i.e not numeric)', () => {
+ expect(maybeBigNumberUtil.toMaybeBigNumber('test')).toEqual(undefined);
+ });
+ it('should return BigNumber (>=v8.0.0) when passed a value as BigNumber (>=v8.0.0)', () => {
+ const bn = maybeBigNumberUtil.toMaybeBigNumber(BIG_NUMBER_1);
+ expect(BigNumber.isBigNumber(bn)).toEqual(true);
+ });
+ it('should return undefined if value is not BigNumber or string', () => {
+ expect(maybeBigNumberUtil.toMaybeBigNumber(true)).toEqual(undefined);
+ });
+ });
+});
diff --git a/packages/instant/test/util/order_coercion.test.ts b/packages/instant/test/util/order_coercion.test.ts
new file mode 100644
index 000000000..f7a958c9d
--- /dev/null
+++ b/packages/instant/test/util/order_coercion.test.ts
@@ -0,0 +1,103 @@
+import { BigNumber } from '@0x/utils';
+
+import { orderCoercionUtil } from '../../src/util/order_coercion';
+
+const ORDER = {
+ senderAddress: '0x0000000000000000000000000000000000000000',
+ makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
+ takerAddress: '0x0000000000000000000000000000000000000000',
+ makerFee: new BigNumber('0'),
+ takerFee: new BigNumber('0'),
+ makerAssetAmount: new BigNumber('200000000000000000000'),
+ takerAssetAmount: new BigNumber('10000000000000000000'),
+ makerAssetData: '0xf47261b00000000000000000000000008cb3971b8eb709c14616bd556ff6683019e90d9c',
+ takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
+ expirationTimeSeconds: new BigNumber('1601535600'),
+ feeRecipientAddress: '0x0000000000000000000000000000000000000000',
+ salt: new BigNumber('3101985707338942582579795423923841749956600670712030922928319824580764688653'),
+ signature:
+ '0x1bd4d5686fea801fe33c68c4944356085e7e6cb553eb7073160abd815609f714e85fb47f44b7ffd0a2a1321ac40d72d55163869d0a50fdb5a402132150fe33a08403',
+ exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2',
+};
+
+const STRING_ORDER = {
+ senderAddress: '0x0000000000000000000000000000000000000000',
+ makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
+ takerAddress: '0x0000000000000000000000000000000000000000',
+ makerFee: '0',
+ takerFee: '0',
+ makerAssetAmount: '300000000000000000000',
+ takerAssetAmount: '31000000000000000000',
+ makerAssetData: '0xf47261b00000000000000000000000002002d3812f58e35f0ea1ffbf80a75a38c32175fa',
+ takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
+ expirationTimeSeconds: '2524636800',
+ feeRecipientAddress: '0x0000000000000000000000000000000000000000',
+ salt: '64592004666704945574675477805199411288137454783320798602050822322450089238268',
+ signature:
+ '0x1c13cacddca8d7d8248e91f412377e68f8f1f9891a59a6c1b2eea9f7b33558c30c4fb86a448e08ab7def40a28fb3a3062dcb33bb3c45302447fce5c4288b7c7f5b03',
+ exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2',
+};
+
+const ORDERS = [ORDER, STRING_ORDER];
+
+describe('orderCoercionUtil', () => {
+ describe('coerceFieldsToBigNumbers', () => {
+ it('should coerce all fields specified to a big number', () => {
+ const coercedOrder = orderCoercionUtil.coerceFieldsToBigNumbers(STRING_ORDER, ['makerFee', 'takerFee']);
+ expect(coercedOrder.makerFee.toString()).toEqual('0');
+ expect(coercedOrder.takerFee.toString()).toEqual('0');
+ });
+ it("should throw if a field can't be found", () => {
+ expect(() => {
+ orderCoercionUtil.coerceFieldsToBigNumbers(ORDER, ['salty']);
+ }).toThrow("Could not find field 'salty' while converting fields to BigNumber.");
+ });
+ it('should not change value if not numeric string or big number', () => {
+ const obj = { number: 'number' };
+ const coercedObj = orderCoercionUtil.coerceFieldsToBigNumbers(obj, ['number']);
+ expect(coercedObj).toEqual({
+ number: 'number',
+ });
+ });
+ });
+ // Note: this doesn't test coercing pre v8.0.0 BigNumber versions to specified one used by 0x
+ describe('coerceOrderFieldsToBigNumber', () => {
+ it('should convert string values in order to big number', () => {
+ const coercedOrder = orderCoercionUtil.coerceOrderFieldsToBigNumber(STRING_ORDER);
+ expect(coercedOrder.makerFee.toString()).toEqual(STRING_ORDER.makerFee);
+ expect(coercedOrder.takerFee.toString()).toEqual(STRING_ORDER.takerFee);
+ expect(coercedOrder.takerAssetAmount.toString()).toEqual(STRING_ORDER.takerAssetAmount);
+ expect(coercedOrder.makerAssetAmount.toString()).toEqual(STRING_ORDER.makerAssetAmount);
+ expect(coercedOrder.salt.toString()).toEqual(STRING_ORDER.salt);
+ expect(coercedOrder.expirationTimeSeconds.toString()).toEqual(STRING_ORDER.expirationTimeSeconds);
+ });
+ it('should convert big number values in order to big number', () => {
+ const coercedOrder = orderCoercionUtil.coerceOrderFieldsToBigNumber(ORDER);
+ expect(coercedOrder.makerFee).toEqual(ORDER.makerFee);
+ expect(coercedOrder.takerFee).toEqual(ORDER.takerFee);
+ expect(coercedOrder.takerAssetAmount).toEqual(ORDER.takerAssetAmount);
+ expect(coercedOrder.makerAssetAmount).toEqual(ORDER.makerAssetAmount);
+ expect(coercedOrder.salt).toEqual(ORDER.salt);
+ expect(coercedOrder.expirationTimeSeconds).toEqual(ORDER.expirationTimeSeconds);
+ });
+ });
+ // Note: this doesn't test coercing pre v8.0.0 BigNumber versions to specified one used by 0x
+ describe('coerceOrderArrayFieldsToBigNumber', () => {
+ it('should convert string values and big numbers in orders to big number', () => {
+ const coercedOrders = orderCoercionUtil.coerceOrderArrayFieldsToBigNumber(ORDERS);
+ expect(coercedOrders[0].makerFee).toEqual(ORDER.makerFee);
+ expect(coercedOrders[0].takerFee).toEqual(ORDER.takerFee);
+ expect(coercedOrders[0].takerAssetAmount).toEqual(ORDER.takerAssetAmount);
+ expect(coercedOrders[0].makerAssetAmount).toEqual(ORDER.makerAssetAmount);
+ expect(coercedOrders[0].salt).toEqual(ORDER.salt);
+ expect(coercedOrders[0].expirationTimeSeconds).toEqual(ORDER.expirationTimeSeconds);
+
+ expect(coercedOrders[1].makerFee.toString()).toEqual(STRING_ORDER.makerFee);
+ expect(coercedOrders[1].takerFee.toString()).toEqual(STRING_ORDER.takerFee);
+ expect(coercedOrders[1].takerAssetAmount.toString()).toEqual(STRING_ORDER.takerAssetAmount);
+ expect(coercedOrders[1].makerAssetAmount.toString()).toEqual(STRING_ORDER.makerAssetAmount);
+ expect(coercedOrders[1].salt.toString()).toEqual(STRING_ORDER.salt);
+ expect(coercedOrders[1].expirationTimeSeconds.toString()).toEqual(STRING_ORDER.expirationTimeSeconds);
+ });
+ });
+});