merge development
This commit is contained in:
		@@ -98,6 +98,7 @@ jobs:
 | 
			
		||||
      - run: yarn wsrun test:circleci @0xproject/subproviders
 | 
			
		||||
      - run: yarn wsrun test:circleci @0xproject/web3-wrapper
 | 
			
		||||
      - run: yarn wsrun test:circleci @0xproject/utils
 | 
			
		||||
      - run: yarn wsrun test:circleci @0xproject/instant
 | 
			
		||||
      - save_cache:
 | 
			
		||||
          key: coverage-abi-gen-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
          paths:
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ lib
 | 
			
		||||
/packages/contracts/generated-artifacts
 | 
			
		||||
/packages/abi-gen-wrappers/src/generated-wrappers
 | 
			
		||||
/packages/contract-artifacts/artifacts
 | 
			
		||||
/packages/json-schemas/schemas
 | 
			
		||||
/packages/metacoin/src/contract_wrappers
 | 
			
		||||
/packages/metacoin/artifacts
 | 
			
		||||
/packages/sra-spec/public/
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								CODEOWNERS
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								CODEOWNERS
									
									
									
									
									
								
							@@ -8,3 +8,21 @@
 | 
			
		||||
packages/asset-buyer/  @BMillman19 @fragosti @steveklebanoff
 | 
			
		||||
packages/instant/  @BMillman19 @fragosti @steveklebanoff
 | 
			
		||||
packages/website/  @BMillman19 @fragosti @fabioberger @steveklebanoff
 | 
			
		||||
 | 
			
		||||
# Dev tools & setup
 | 
			
		||||
packages/abi-gen/ @LogvinovLeon
 | 
			
		||||
packages/base-contract/ @LogvinovLeon
 | 
			
		||||
packages/contract_templates/ @LogvinovLeon
 | 
			
		||||
packages/dev-utils/ @LogvinovLeon @fabioberger
 | 
			
		||||
 | 
			
		||||
packages/ethereum-types/ @LogvinovLeon
 | 
			
		||||
packages/metacoin/ @LogvinovLeon
 | 
			
		||||
packages/sol-compiler/ @LogvinovLeon
 | 
			
		||||
packages/sol-cov/ @LogvinovLeon
 | 
			
		||||
packages/sol-resolver/ @LogvinovLeon
 | 
			
		||||
packages/web3-wrapper/ @LogvinovLeon @fabioberger
 | 
			
		||||
.circleci/ @LogvinovLeon
 | 
			
		||||
packages/subproviders/ @fabioberger @dekz
 | 
			
		||||
packages/connect/ @fragosti 
 | 
			
		||||
packages/monorepo-scripts/ @fabioberger
 | 
			
		||||
packages/order-utils/ @fabioberger @LogvinovLeon 
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "config": {
 | 
			
		||||
        "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic",
 | 
			
		||||
        "packagesWithDocPages": "0x.js connect json-schemas subproviders web3-wrapper contract-wrappers order-utils order-watcher sol-compiler sol-cov ethereum-types"
 | 
			
		||||
        "packagesWithDocPages": "0x.js connect json-schemas subproviders web3-wrapper contract-wrappers order-utils order-watcher sol-compiler sol-cov ethereum-types asset-buyer"
 | 
			
		||||
    },
 | 
			
		||||
    "bundlewatch" : {
 | 
			
		||||
        "files": [
 | 
			
		||||
@@ -50,7 +50,7 @@
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "path": "packages/instant/public/main.bundle.js",
 | 
			
		||||
                "maxSize": "350kB"
 | 
			
		||||
                "maxSize": "500kB"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "ci": {
 | 
			
		||||
@@ -65,7 +65,7 @@
 | 
			
		||||
        "coveralls": "^3.0.0",
 | 
			
		||||
        "ganache-cli": "6.1.8",
 | 
			
		||||
        "lcov-result-merger": "^3.0.0",
 | 
			
		||||
        "npm-cli-login": "^0.0.10",
 | 
			
		||||
        "@0xproject/npm-cli-login": "^0.0.11",
 | 
			
		||||
        "npm-run-all": "^4.1.2",
 | 
			
		||||
        "prettier": "^1.11.1",
 | 
			
		||||
        "source-map-support": "^0.5.6",
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,10 @@
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Make web3-provider-engine types a 'dependency' so it's available to users of the library",
 | 
			
		||||
                "pr": 1105
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Export new `AssetData` type from types",
 | 
			
		||||
                "pr": 1131
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,7 @@
 | 
			
		||||
        "sinon": "^4.0.0",
 | 
			
		||||
        "source-map-support": "^0.5.0",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typedoc": "0.12.0",
 | 
			
		||||
        "typedoc": "0.13.0",
 | 
			
		||||
        "typescript": "3.0.1",
 | 
			
		||||
        "uglifyjs-webpack-plugin": "^2.0.1",
 | 
			
		||||
        "webpack": "^4.20.2"
 | 
			
		||||
 
 | 
			
		||||
@@ -79,6 +79,7 @@ export {
 | 
			
		||||
    OrderStateInvalid,
 | 
			
		||||
    OrderState,
 | 
			
		||||
    AssetProxyId,
 | 
			
		||||
    AssetData,
 | 
			
		||||
    ERC20AssetData,
 | 
			
		||||
    ERC721AssetData,
 | 
			
		||||
    SignatureType,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,10 +5,26 @@
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add `gasLimit` and `gasPrice` as optional properties on `BuyQuoteExecutionOpts`"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Export `BuyQuoteInfo` type",
 | 
			
		||||
                "pr": 1131
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note":
 | 
			
		||||
                    "Updated to use new modularized artifacts and the latest version of @0xproject/contract-wrappers",
 | 
			
		||||
                "pr": 1105
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add `gasLimit` and `gasPrice` as optional properties on `BuyQuoteExecutionOpts`",
 | 
			
		||||
                "pr": 1116
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add `docs:json` command to package.json",
 | 
			
		||||
                "pr": 1139
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add missing types to public interface",
 | 
			
		||||
                "pr": 1139
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,8 @@
 | 
			
		||||
        "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
 | 
			
		||||
        "test:circleci": "yarn test:coverage",
 | 
			
		||||
        "run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --exit",
 | 
			
		||||
        "clean": "shx rm -rf lib test_temp"
 | 
			
		||||
        "clean": "shx rm -rf lib test_temp",
 | 
			
		||||
        "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
 | 
			
		||||
    },
 | 
			
		||||
    "config": {
 | 
			
		||||
        "postpublish": {
 | 
			
		||||
@@ -63,7 +64,7 @@
 | 
			
		||||
        "nyc": "^11.0.1",
 | 
			
		||||
        "shx": "^0.2.2",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typedoc": "0.12.0",
 | 
			
		||||
        "typedoc": "0.13.0",
 | 
			
		||||
        "typescript": "3.0.1"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,10 @@
 | 
			
		||||
export { Provider } from 'ethereum-types';
 | 
			
		||||
export {
 | 
			
		||||
    JSONRPCRequestPayload,
 | 
			
		||||
    JSONRPCResponsePayload,
 | 
			
		||||
    JSONRPCResponseError,
 | 
			
		||||
    JSONRPCErrorCallback,
 | 
			
		||||
    Provider,
 | 
			
		||||
} from 'ethereum-types';
 | 
			
		||||
export { SignedOrder } from '@0xproject/types';
 | 
			
		||||
export { BigNumber } from '@0xproject/utils';
 | 
			
		||||
 | 
			
		||||
@@ -10,6 +16,7 @@ export {
 | 
			
		||||
    AssetBuyerOpts,
 | 
			
		||||
    BuyQuote,
 | 
			
		||||
    BuyQuoteExecutionOpts,
 | 
			
		||||
    BuyQuoteInfo,
 | 
			
		||||
    BuyQuoteRequestOpts,
 | 
			
		||||
    OrderProvider,
 | 
			
		||||
    OrderProviderRequest,
 | 
			
		||||
 
 | 
			
		||||
@@ -129,7 +129,8 @@ export class BaseContract {
 | 
			
		||||
            if (abiDefinition.type !== AbiType.Function) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            const abiFunctionSignature = abiUtils.getFunctionSignature(abiDefinition);
 | 
			
		||||
            // tslint:disable-next-line:no-unnecessary-type-assertion
 | 
			
		||||
            const abiFunctionSignature = abiUtils.getFunctionSignature(abiDefinition as MethodAbi);
 | 
			
		||||
            if (abiFunctionSignature === functionSignature) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -77,7 +77,7 @@
 | 
			
		||||
        "nyc": "^11.0.1",
 | 
			
		||||
        "shx": "^0.2.2",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typedoc": "0.12.0",
 | 
			
		||||
        "typedoc": "0.13.0",
 | 
			
		||||
        "typescript": "3.0.1"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ export const assert = {
 | 
			
		||||
        sharedAssert.doesConformToSchema(
 | 
			
		||||
            variableName,
 | 
			
		||||
            subscriptionOpts,
 | 
			
		||||
            schemas.relayerApiOrdersChannelSubscribePayload,
 | 
			
		||||
            schemas.relayerApiOrdersChannelSubscribePayloadSchema,
 | 
			
		||||
        );
 | 
			
		||||
    },
 | 
			
		||||
    isOrdersChannelHandler(variableName: string, handler: any): void {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,19 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.0",
 | 
			
		||||
        "version": "1.0.1",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "pr": 1105,
 | 
			
		||||
                "note": "Initial release"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Unpublished Package"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,19 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.0",
 | 
			
		||||
        "version": "1.0.1",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "pr": 1105,
 | 
			
		||||
                "note": "Initial release"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Unpublished Package"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@
 | 
			
		||||
        "sinon": "^4.0.0",
 | 
			
		||||
        "source-map-support": "^0.5.0",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typedoc": "0.12.0",
 | 
			
		||||
        "typedoc": "0.13.0",
 | 
			
		||||
        "typescript": "3.0.1",
 | 
			
		||||
        "web3-provider-engine": "14.0.6"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,9 @@ export type ConstructorStateMutability = 'nonpayable' | 'payable';
 | 
			
		||||
export type StateMutability = 'pure' | 'view' | ConstructorStateMutability;
 | 
			
		||||
 | 
			
		||||
export interface MethodAbi {
 | 
			
		||||
    type: 'function'; // We hardcode this here b/c doc pages cannot render an enum value
 | 
			
		||||
    // Ideally this would be set to: `'function'` but then TS complains when artifacts are loaded
 | 
			
		||||
    // from JSON files, and this value has type `string` not type `'function'`
 | 
			
		||||
    type: string;
 | 
			
		||||
    name: string;
 | 
			
		||||
    inputs: DataItem[];
 | 
			
		||||
    outputs: DataItem[];
 | 
			
		||||
@@ -30,14 +32,18 @@ export interface MethodAbi {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ConstructorAbi {
 | 
			
		||||
    type: 'constructor'; // We hardcode this here b/c doc pages cannot render an enum value
 | 
			
		||||
    // Ideally this would be set to: `'constructor'` but then TS complains when artifacts are loaded
 | 
			
		||||
    // from JSON files, and this value has type `string` not type `'constructor'`
 | 
			
		||||
    type: string;
 | 
			
		||||
    inputs: DataItem[];
 | 
			
		||||
    payable: boolean;
 | 
			
		||||
    stateMutability: ConstructorStateMutability;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface FallbackAbi {
 | 
			
		||||
    type: 'fallback'; // We hardcode this here b/c doc pages cannot render an enum value
 | 
			
		||||
    // Ideally this would be set to: `'fallback'` but then TS complains when artifacts are loaded
 | 
			
		||||
    // from JSON files, and this value has type `string` not type `'fallback'`
 | 
			
		||||
    type: string;
 | 
			
		||||
    payable: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -46,7 +52,9 @@ export interface EventParameter extends DataItem {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface EventAbi {
 | 
			
		||||
    type: 'event'; // We hardcode this here b/c doc pages cannot render an enum value
 | 
			
		||||
    // Ideally this would be set to: `'event'` but then TS complains when artifacts are loaded
 | 
			
		||||
    // from JSON files, and this value has type `string` not type `'event'`
 | 
			
		||||
    type: string;
 | 
			
		||||
    name: string;
 | 
			
		||||
    inputs: EventParameter[];
 | 
			
		||||
    anonymous: boolean;
 | 
			
		||||
 
 | 
			
		||||
@@ -55,12 +55,15 @@
 | 
			
		||||
        "react-dom": "^16.5.2",
 | 
			
		||||
        "react-redux": "^5.0.7",
 | 
			
		||||
        "redux": "^4.0.0",
 | 
			
		||||
        "styled-components": "^3.4.9"
 | 
			
		||||
        "redux-devtools-extension": "^2.13.5",
 | 
			
		||||
        "styled-components": "^3.4.9",
 | 
			
		||||
        "ts-optchain": "^0.1.1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0xproject/tslint-config": "^1.0.8",
 | 
			
		||||
        "@types/enzyme": "^3.1.14",
 | 
			
		||||
        "@types/enzyme-adapter-react-16": "^1.0.3",
 | 
			
		||||
        "@types/jest": "^23.3.5",
 | 
			
		||||
        "@types/lodash": "^4.14.116",
 | 
			
		||||
        "@types/node": "*",
 | 
			
		||||
        "@types/react": "^16.4.16",
 | 
			
		||||
@@ -77,7 +80,7 @@
 | 
			
		||||
        "shx": "^0.2.2",
 | 
			
		||||
        "ts-jest": "^23.10.3",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typedoc": "0.12.0",
 | 
			
		||||
        "typedoc": "0.13.0",
 | 
			
		||||
        "typescript": "3.0.1",
 | 
			
		||||
        "webpack": "^4.20.2",
 | 
			
		||||
        "webpack-cli": "^3.1.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { util } from '../util/util';
 | 
			
		||||
 | 
			
		||||
import { Container, Input } from './ui';
 | 
			
		||||
 | 
			
		||||
@@ -10,10 +11,13 @@ export interface AmountInputProps {
 | 
			
		||||
    fontColor?: ColorOption;
 | 
			
		||||
    fontSize?: string;
 | 
			
		||||
    value?: BigNumber;
 | 
			
		||||
    onChange?: (value?: BigNumber) => void;
 | 
			
		||||
    onChange: (value?: BigNumber) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class AmountInput extends React.Component<AmountInputProps> {
 | 
			
		||||
    public static defaultProps = {
 | 
			
		||||
        onChange: util.boundNoop,
 | 
			
		||||
    };
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { fontColor, fontSize, value } = this.props;
 | 
			
		||||
        return (
 | 
			
		||||
@@ -24,7 +28,7 @@ export class AmountInput extends React.Component<AmountInputProps> {
 | 
			
		||||
                    onChange={this._handleChange}
 | 
			
		||||
                    value={!_.isUndefined(value) ? value.toString() : ''}
 | 
			
		||||
                    placeholder="0.00"
 | 
			
		||||
                    width="2em"
 | 
			
		||||
                    width="2.2em"
 | 
			
		||||
                />
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
@@ -40,8 +44,6 @@ export class AmountInput extends React.Component<AmountInputProps> {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!_.isUndefined(this.props.onChange)) {
 | 
			
		||||
            this.props.onChange(bigNumberValue);
 | 
			
		||||
        }
 | 
			
		||||
        this.props.onChange(bigNumberValue);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,54 @@
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { keyframes, styled } from '../../style/theme';
 | 
			
		||||
 | 
			
		||||
const slideKeyframeGenerator = (fromY: string, toY: string) => keyframes`
 | 
			
		||||
    from {
 | 
			
		||||
        position: relative;
 | 
			
		||||
        top: ${fromY};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    to {
 | 
			
		||||
        position: relative;
 | 
			
		||||
        top: ${toY};
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
export interface SlideAnimationProps {
 | 
			
		||||
    keyframes: string;
 | 
			
		||||
    animationType: string;
 | 
			
		||||
    animationDirection?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const SlideAnimation =
 | 
			
		||||
    styled.div <
 | 
			
		||||
    SlideAnimationProps >
 | 
			
		||||
    `
 | 
			
		||||
    animation-name: ${props => props.keyframes};
 | 
			
		||||
    animation-duration: 0.3s;
 | 
			
		||||
    animation-timing-function: ${props => props.animationType};
 | 
			
		||||
    animation-delay: 0s;
 | 
			
		||||
    animation-iteration-count: 1;
 | 
			
		||||
    animation-fill-mode: ${props => props.animationDirection || 'none'};
 | 
			
		||||
    position: relative;
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
export interface SlideAnimationComponentProps {
 | 
			
		||||
    downY: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const SlideUpAnimation: React.StatelessComponent<SlideAnimationComponentProps> = props => (
 | 
			
		||||
    <SlideAnimation animationType="ease-in" keyframes={slideKeyframeGenerator(props.downY, '0px')}>
 | 
			
		||||
        {props.children}
 | 
			
		||||
    </SlideAnimation>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const SlideDownAnimation: React.StatelessComponent<SlideAnimationComponentProps> = props => (
 | 
			
		||||
    <SlideAnimation
 | 
			
		||||
        animationDirection="forwards"
 | 
			
		||||
        animationType="cubic-bezier(0.25, 0.1, 0.25, 1)"
 | 
			
		||||
        keyframes={slideKeyframeGenerator('0px', props.downY)}
 | 
			
		||||
    >
 | 
			
		||||
        {props.children}
 | 
			
		||||
    </SlideAnimation>
 | 
			
		||||
);
 | 
			
		||||
@@ -1,96 +0,0 @@
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { keyframes, styled } from '../../style/theme';
 | 
			
		||||
 | 
			
		||||
const slideKeyframeGenerator = (fromY: string, toY: string) => keyframes`
 | 
			
		||||
    from {
 | 
			
		||||
        position: relative;
 | 
			
		||||
        top: ${fromY};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    to {
 | 
			
		||||
        position: relative;
 | 
			
		||||
        top: ${toY};
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
export interface SlideAnimationProps {
 | 
			
		||||
    keyframes: string;
 | 
			
		||||
    animationType: string;
 | 
			
		||||
    animationDirection?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const SlideAnimation =
 | 
			
		||||
    styled.div <
 | 
			
		||||
    SlideAnimationProps >
 | 
			
		||||
    `
 | 
			
		||||
    animation-name: ${props => props.keyframes};
 | 
			
		||||
    animation-duration: 0.3s;
 | 
			
		||||
    animation-timing-function: ${props => props.animationType};
 | 
			
		||||
    animation-delay: 0s;
 | 
			
		||||
    animation-iteration-count: 1;
 | 
			
		||||
    animation-fill-mode: ${props => props.animationDirection || 'none'};
 | 
			
		||||
    position: relative;
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
export interface SlideAnimationComponentProps {
 | 
			
		||||
    downY: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const SlideUpAnimationComponent: React.StatelessComponent<SlideAnimationComponentProps> = props => (
 | 
			
		||||
    <SlideAnimation animationType="ease-in" keyframes={slideKeyframeGenerator(props.downY, '0px')}>
 | 
			
		||||
        {props.children}
 | 
			
		||||
    </SlideAnimation>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const SlideDownAnimationComponent: React.StatelessComponent<SlideAnimationComponentProps> = props => (
 | 
			
		||||
    <SlideAnimation
 | 
			
		||||
        animationDirection="forwards"
 | 
			
		||||
        animationType="cubic-bezier(0.25, 0.1, 0.25, 1)"
 | 
			
		||||
        keyframes={slideKeyframeGenerator('0px', props.downY)}
 | 
			
		||||
    >
 | 
			
		||||
        {props.children}
 | 
			
		||||
    </SlideAnimation>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export interface SlideUpAndDownAnimationProps extends SlideAnimationComponentProps {
 | 
			
		||||
    delayMs: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum SlideState {
 | 
			
		||||
    Up = 'up',
 | 
			
		||||
    Down = 'down',
 | 
			
		||||
}
 | 
			
		||||
interface SlideUpAndDownState {
 | 
			
		||||
    slideState: SlideState;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class SlideUpAndDownAnimation extends React.Component<SlideUpAndDownAnimationProps, SlideUpAndDownState> {
 | 
			
		||||
    public state = {
 | 
			
		||||
        slideState: SlideState.Up,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private _timeoutId?: number;
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        return this._renderSlide();
 | 
			
		||||
    }
 | 
			
		||||
    public componentDidMount(): void {
 | 
			
		||||
        this._timeoutId = window.setTimeout(() => {
 | 
			
		||||
            this.setState({
 | 
			
		||||
                slideState: SlideState.Down,
 | 
			
		||||
            });
 | 
			
		||||
        }, this.props.delayMs);
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    public componentWillUnmount(): void {
 | 
			
		||||
        if (this._timeoutId) {
 | 
			
		||||
            window.clearTimeout(this._timeoutId);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private _renderSlide(): React.ReactNode {
 | 
			
		||||
        const SlideComponent = this.state.slideState === 'up' ? SlideUpAnimationComponent : SlideDownAnimationComponent;
 | 
			
		||||
 | 
			
		||||
        return <SlideComponent downY={this.props.downY}>{this.props.children}</SlideComponent>;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								packages/instant/src/components/asset_amount_input.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								packages/instant/src/components/asset_amount_input.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { assetDataUtil } from '../util/asset_data';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { util } from '../util/util';
 | 
			
		||||
 | 
			
		||||
import { AmountInput, AmountInputProps } from './amount_input';
 | 
			
		||||
import { Container, Text } from './ui';
 | 
			
		||||
 | 
			
		||||
export interface AssetAmountInputProps extends AmountInputProps {
 | 
			
		||||
    assetData?: string;
 | 
			
		||||
    onChange: (value?: BigNumber, assetData?: string) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class AssetAmountInput extends React.Component<AssetAmountInputProps> {
 | 
			
		||||
    public static defaultProps = {
 | 
			
		||||
        onChange: util.boundNoop,
 | 
			
		||||
    };
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { assetData, onChange, ...rest } = this.props;
 | 
			
		||||
        return (
 | 
			
		||||
            <Container>
 | 
			
		||||
                <AmountInput {...rest} onChange={this._handleChange} />
 | 
			
		||||
                <Container display="inline-block" marginLeft="10px">
 | 
			
		||||
                    <Text fontSize={rest.fontSize} fontColor={ColorOption.white} textTransform="uppercase">
 | 
			
		||||
                        {assetDataUtil.bestNameForAsset(this.props.assetData, '???')}
 | 
			
		||||
                    </Text>
 | 
			
		||||
                </Container>
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private readonly _handleChange = (value?: BigNumber): void => {
 | 
			
		||||
        this.props.onChange(value, this.props.assetData);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +1,53 @@
 | 
			
		||||
import { BuyQuote } from '@0xproject/asset-buyer';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { assetBuyer } from '../util/asset_buyer';
 | 
			
		||||
import { util } from '../util/util';
 | 
			
		||||
import { web3Wrapper } from '../util/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
import { Button, Container, Text } from './ui';
 | 
			
		||||
 | 
			
		||||
export interface BuyButtonProps {}
 | 
			
		||||
export interface BuyButtonProps {
 | 
			
		||||
    buyQuote?: BuyQuote;
 | 
			
		||||
    onClick: (buyQuote: BuyQuote) => void;
 | 
			
		||||
    onBuySuccess: (buyQuote: BuyQuote, txnHash: string) => void;
 | 
			
		||||
    onBuyFailure: (buyQuote: BuyQuote, tnxHash?: string) => void;
 | 
			
		||||
    text: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const BuyButton: React.StatelessComponent<BuyButtonProps> = props => (
 | 
			
		||||
    <Container padding="20px" width="100%">
 | 
			
		||||
        <Button width="100%">
 | 
			
		||||
            <Text fontColor={ColorOption.white} fontWeight={600} fontSize="20px">
 | 
			
		||||
                Buy
 | 
			
		||||
            </Text>
 | 
			
		||||
        </Button>
 | 
			
		||||
    </Container>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
BuyButton.displayName = 'BuyButton';
 | 
			
		||||
export class BuyButton extends React.Component<BuyButtonProps> {
 | 
			
		||||
    public static defaultProps = {
 | 
			
		||||
        onClick: util.boundNoop,
 | 
			
		||||
        onBuySuccess: util.boundNoop,
 | 
			
		||||
        onBuyFailure: util.boundNoop,
 | 
			
		||||
    };
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const shouldDisableButton = _.isUndefined(this.props.buyQuote);
 | 
			
		||||
        return (
 | 
			
		||||
            <Container padding="20px" width="100%">
 | 
			
		||||
                <Button width="100%" onClick={this._handleClick} isDisabled={shouldDisableButton}>
 | 
			
		||||
                    <Text fontColor={ColorOption.white} fontWeight={600} fontSize="20px">
 | 
			
		||||
                        {this.props.text}
 | 
			
		||||
                    </Text>
 | 
			
		||||
                </Button>
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private readonly _handleClick = async () => {
 | 
			
		||||
        // The button is disabled when there is no buy quote anyway.
 | 
			
		||||
        if (_.isUndefined(this.props.buyQuote)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        this.props.onClick(this.props.buyQuote);
 | 
			
		||||
        let txnHash;
 | 
			
		||||
        try {
 | 
			
		||||
            txnHash = await assetBuyer.executeBuyQuoteAsync(this.props.buyQuote);
 | 
			
		||||
            await web3Wrapper.awaitTransactionSuccessAsync(txnHash);
 | 
			
		||||
            this.props.onBuySuccess(this.props.buyQuote, txnHash);
 | 
			
		||||
        } catch {
 | 
			
		||||
            this.props.onBuyFailure(this.props.buyQuote, txnHash);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,58 @@
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { SelectedAssetAmountInput } from '../containers/selected_asset_amount_input';
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { AsyncProcessState } from '../types';
 | 
			
		||||
import { format } from '../util/format';
 | 
			
		||||
 | 
			
		||||
import { Container, Flex, Text } from './ui';
 | 
			
		||||
 | 
			
		||||
export interface InstantHeadingProps {}
 | 
			
		||||
export interface InstantHeadingProps {
 | 
			
		||||
    selectedAssetAmount?: BigNumber;
 | 
			
		||||
    totalEthBaseAmount?: BigNumber;
 | 
			
		||||
    ethUsdPrice?: BigNumber;
 | 
			
		||||
    quoteState: AsyncProcessState;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Placeholder = () => (
 | 
			
		||||
    <Text fontWeight="bold" fontColor={ColorOption.white}>
 | 
			
		||||
        —
 | 
			
		||||
    </Text>
 | 
			
		||||
);
 | 
			
		||||
const displaytotalEthBaseAmount = ({
 | 
			
		||||
    selectedAssetAmount,
 | 
			
		||||
    totalEthBaseAmount,
 | 
			
		||||
}: InstantHeadingProps): React.ReactNode => {
 | 
			
		||||
    if (_.isUndefined(selectedAssetAmount)) {
 | 
			
		||||
        return '0 ETH';
 | 
			
		||||
    }
 | 
			
		||||
    return format.ethBaseAmount(totalEthBaseAmount, 4, <Placeholder />);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const displayUsdAmount = ({
 | 
			
		||||
    totalEthBaseAmount,
 | 
			
		||||
    selectedAssetAmount,
 | 
			
		||||
    ethUsdPrice,
 | 
			
		||||
}: InstantHeadingProps): React.ReactNode => {
 | 
			
		||||
    if (_.isUndefined(selectedAssetAmount)) {
 | 
			
		||||
        return '$0.00';
 | 
			
		||||
    }
 | 
			
		||||
    return format.ethBaseAmountInUsd(totalEthBaseAmount, ethUsdPrice, 2, <Placeholder />);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const loadingOrAmount = (quoteState: AsyncProcessState, amount: React.ReactNode): React.ReactNode => {
 | 
			
		||||
    if (quoteState === AsyncProcessState.PENDING) {
 | 
			
		||||
        return (
 | 
			
		||||
            <Text fontWeight="bold" fontColor={ColorOption.white}>
 | 
			
		||||
                …loading
 | 
			
		||||
            </Text>
 | 
			
		||||
        );
 | 
			
		||||
    } else {
 | 
			
		||||
        return amount;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const InstantHeading: React.StatelessComponent<InstantHeadingProps> = props => (
 | 
			
		||||
    <Container backgroundColor={ColorOption.primaryColor} padding="20px" width="100%" borderRadius="3px 3px 0px 0px">
 | 
			
		||||
@@ -22,22 +69,15 @@ export const InstantHeading: React.StatelessComponent<InstantHeadingProps> = pro
 | 
			
		||||
            </Text>
 | 
			
		||||
        </Container>
 | 
			
		||||
        <Flex direction="row" justify="space-between">
 | 
			
		||||
            <Container>
 | 
			
		||||
                <SelectedAssetAmountInput fontSize="45px" />
 | 
			
		||||
                <Container display="inline-block" marginLeft="10px">
 | 
			
		||||
                    <Text fontSize="45px" fontColor={ColorOption.white} textTransform="uppercase">
 | 
			
		||||
                        rep
 | 
			
		||||
                    </Text>
 | 
			
		||||
                </Container>
 | 
			
		||||
            </Container>
 | 
			
		||||
            <SelectedAssetAmountInput fontSize="45px" />
 | 
			
		||||
            <Flex direction="column" justify="space-between">
 | 
			
		||||
                <Container marginBottom="5px">
 | 
			
		||||
                    <Text fontSize="16px" fontColor={ColorOption.white} fontWeight={500}>
 | 
			
		||||
                        0 ETH
 | 
			
		||||
                        {loadingOrAmount(props.quoteState, displaytotalEthBaseAmount(props))}
 | 
			
		||||
                    </Text>
 | 
			
		||||
                </Container>
 | 
			
		||||
                <Text fontSize="16px" fontColor={ColorOption.white} opacity={0.7}>
 | 
			
		||||
                    $0.00
 | 
			
		||||
                    {loadingOrAmount(props.quoteState, displayUsdAmount(props))}
 | 
			
		||||
                </Text>
 | 
			
		||||
            </Flex>
 | 
			
		||||
        </Flex>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,53 +1,90 @@
 | 
			
		||||
import { BuyQuoteInfo } from '@0xproject/asset-buyer';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
import { oc } from 'ts-optchain';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { format } from '../util/format';
 | 
			
		||||
 | 
			
		||||
import { Container, Flex, Text } from './ui';
 | 
			
		||||
 | 
			
		||||
export interface OrderDetailsProps {}
 | 
			
		||||
export interface OrderDetailsProps {
 | 
			
		||||
    buyQuoteInfo?: BuyQuoteInfo;
 | 
			
		||||
    ethUsdPrice?: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const OrderDetails: React.StatelessComponent<OrderDetailsProps> = props => (
 | 
			
		||||
    <Container padding="20px" width="100%">
 | 
			
		||||
        <Container marginBottom="10px">
 | 
			
		||||
            <Text
 | 
			
		||||
                letterSpacing="1px"
 | 
			
		||||
                fontColor={ColorOption.primaryColor}
 | 
			
		||||
                fontWeight={600}
 | 
			
		||||
                textTransform="uppercase"
 | 
			
		||||
                fontSize="14px"
 | 
			
		||||
            >
 | 
			
		||||
                Order Details
 | 
			
		||||
            </Text>
 | 
			
		||||
        </Container>
 | 
			
		||||
        <OrderDetailsRow name="Token Price" primaryValue=".013 ETH" secondaryValue="$24.32" />
 | 
			
		||||
        <OrderDetailsRow name="Fee" primaryValue=".005 ETH" secondaryValue="$1.04" />
 | 
			
		||||
        <OrderDetailsRow name="Total Cost" primaryValue="1.66 ETH" secondaryValue="$589.56" shouldEmphasize={true} />
 | 
			
		||||
    </Container>
 | 
			
		||||
);
 | 
			
		||||
export class OrderDetails extends React.Component<OrderDetailsProps> {
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { buyQuoteInfo, ethUsdPrice } = this.props;
 | 
			
		||||
        const buyQuoteAccessor = oc(buyQuoteInfo);
 | 
			
		||||
        const ethAssetPrice = buyQuoteAccessor.ethPerAssetPrice();
 | 
			
		||||
        const ethTokenFee = buyQuoteAccessor.feeEthAmount();
 | 
			
		||||
        const totalEthAmount = buyQuoteAccessor.totalEthAmount();
 | 
			
		||||
        return (
 | 
			
		||||
            <Container padding="20px" width="100%">
 | 
			
		||||
                <Container marginBottom="10px">
 | 
			
		||||
                    <Text
 | 
			
		||||
                        letterSpacing="1px"
 | 
			
		||||
                        fontColor={ColorOption.primaryColor}
 | 
			
		||||
                        fontWeight={600}
 | 
			
		||||
                        textTransform="uppercase"
 | 
			
		||||
                        fontSize="14px"
 | 
			
		||||
                    >
 | 
			
		||||
                        Order Details
 | 
			
		||||
                    </Text>
 | 
			
		||||
                </Container>
 | 
			
		||||
                <EthAmountRow
 | 
			
		||||
                    rowLabel="Token Price"
 | 
			
		||||
                    ethAmount={ethAssetPrice}
 | 
			
		||||
                    ethUsdPrice={ethUsdPrice}
 | 
			
		||||
                    isEthAmountInBaseUnits={false}
 | 
			
		||||
                />
 | 
			
		||||
                <EthAmountRow rowLabel="Fee" ethAmount={ethTokenFee} ethUsdPrice={ethUsdPrice} />
 | 
			
		||||
                <EthAmountRow
 | 
			
		||||
                    rowLabel="Total Cost"
 | 
			
		||||
                    ethAmount={totalEthAmount}
 | 
			
		||||
                    ethUsdPrice={ethUsdPrice}
 | 
			
		||||
                    shouldEmphasize={true}
 | 
			
		||||
                />
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OrderDetails.displayName = 'OrderDetails';
 | 
			
		||||
 | 
			
		||||
export interface OrderDetailsRowProps {
 | 
			
		||||
    name: string;
 | 
			
		||||
    primaryValue: string;
 | 
			
		||||
    secondaryValue: string;
 | 
			
		||||
export interface EthAmountRowProps {
 | 
			
		||||
    rowLabel: string;
 | 
			
		||||
    ethAmount?: BigNumber;
 | 
			
		||||
    isEthAmountInBaseUnits?: boolean;
 | 
			
		||||
    ethUsdPrice?: BigNumber;
 | 
			
		||||
    shouldEmphasize?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const OrderDetailsRow: React.StatelessComponent<OrderDetailsRowProps> = props => {
 | 
			
		||||
    const fontWeight = props.shouldEmphasize ? 700 : 400;
 | 
			
		||||
export const EthAmountRow: React.StatelessComponent<EthAmountRowProps> = ({
 | 
			
		||||
    rowLabel,
 | 
			
		||||
    ethAmount,
 | 
			
		||||
    isEthAmountInBaseUnits,
 | 
			
		||||
    ethUsdPrice,
 | 
			
		||||
    shouldEmphasize,
 | 
			
		||||
}) => {
 | 
			
		||||
    const fontWeight = shouldEmphasize ? 700 : 400;
 | 
			
		||||
    const usdFormatter = isEthAmountInBaseUnits ? format.ethBaseAmountInUsd : format.ethUnitAmountInUsd;
 | 
			
		||||
    const ethFormatter = isEthAmountInBaseUnits ? format.ethBaseAmount : format.ethUnitAmount;
 | 
			
		||||
    const usdPriceSection = _.isUndefined(ethUsdPrice) ? null : (
 | 
			
		||||
        <Container marginRight="3px" display="inline-block">
 | 
			
		||||
            <Text fontColor={ColorOption.lightGrey}>({usdFormatter(ethAmount, ethUsdPrice)})</Text>
 | 
			
		||||
        </Container>
 | 
			
		||||
    );
 | 
			
		||||
    return (
 | 
			
		||||
        <Container padding="10px 0px" borderTop="1px dashed" borderColor={ColorOption.feintGrey}>
 | 
			
		||||
            <Flex justify="space-between">
 | 
			
		||||
                <Text fontWeight={fontWeight} fontColor={ColorOption.grey}>
 | 
			
		||||
                    {props.name}
 | 
			
		||||
                    {rowLabel}
 | 
			
		||||
                </Text>
 | 
			
		||||
                <Container>
 | 
			
		||||
                    <Container marginRight="3px" display="inline-block">
 | 
			
		||||
                        <Text fontColor={ColorOption.lightGrey}>({props.secondaryValue}) </Text>
 | 
			
		||||
                    </Container>
 | 
			
		||||
                    {usdPriceSection}
 | 
			
		||||
                    <Text fontWeight={fontWeight} fontColor={ColorOption.grey}>
 | 
			
		||||
                        {props.primaryValue}
 | 
			
		||||
                        {ethFormatter(ethAmount)}
 | 
			
		||||
                    </Text>
 | 
			
		||||
                </Container>
 | 
			
		||||
            </Flex>
 | 
			
		||||
@@ -55,8 +92,9 @@ export const OrderDetailsRow: React.StatelessComponent<OrderDetailsRowProps> = p
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
OrderDetailsRow.defaultProps = {
 | 
			
		||||
EthAmountRow.defaultProps = {
 | 
			
		||||
    shouldEmphasize: false,
 | 
			
		||||
    isEthAmountInBaseUnits: true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
OrderDetailsRow.displayName = 'OrderDetailsRow';
 | 
			
		||||
EthAmountRow.displayName = 'EthAmountRow';
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
 | 
			
		||||
import { SlideUpAndDownAnimation } from './animations/slide_up_and_down_animation';
 | 
			
		||||
import { SlideDownAnimation, SlideUpAnimation } from './animations/slide_animations';
 | 
			
		||||
 | 
			
		||||
import { Container, Text } from './ui';
 | 
			
		||||
 | 
			
		||||
@@ -20,8 +20,8 @@ export const Error: React.StatelessComponent<ErrorProps> = props => (
 | 
			
		||||
        borderRadius="6px"
 | 
			
		||||
        marginBottom="10px"
 | 
			
		||||
    >
 | 
			
		||||
        <Container marginRight="5px" display="inline">
 | 
			
		||||
            {props.icon}
 | 
			
		||||
        <Container marginRight="5px" display="inline" top="3px" position="relative">
 | 
			
		||||
            <Text fontSize="20px">{props.icon}</Text>
 | 
			
		||||
        </Container>
 | 
			
		||||
        <Text fontWeight="500" fontColor={ColorOption.darkOrange}>
 | 
			
		||||
            {props.message}
 | 
			
		||||
@@ -29,8 +29,16 @@ export const Error: React.StatelessComponent<ErrorProps> = props => (
 | 
			
		||||
    </Container>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const SlidingError: React.StatelessComponent<ErrorProps> = props => (
 | 
			
		||||
    <SlideUpAndDownAnimation downY="120px" delayMs={5000}>
 | 
			
		||||
        <Error icon={props.icon} message={props.message} />
 | 
			
		||||
    </SlideUpAndDownAnimation>
 | 
			
		||||
);
 | 
			
		||||
export type SlidingDirection = 'up' | 'down';
 | 
			
		||||
export interface SlidingErrorProps extends ErrorProps {
 | 
			
		||||
    direction: SlidingDirection;
 | 
			
		||||
}
 | 
			
		||||
export const SlidingError: React.StatelessComponent<SlidingErrorProps> = props => {
 | 
			
		||||
    const AnimationComponent = props.direction === 'up' ? SlideUpAnimation : SlideDownAnimation;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <AnimationComponent downY="120px">
 | 
			
		||||
            <Error icon={props.icon} message={props.message} />
 | 
			
		||||
        </AnimationComponent>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
import { Provider } from 'react-redux';
 | 
			
		||||
 | 
			
		||||
import { asyncData } from '../redux/async_data';
 | 
			
		||||
import { store } from '../redux/store';
 | 
			
		||||
import { fonts } from '../style/fonts';
 | 
			
		||||
import { theme, ThemeProvider } from '../style/theme';
 | 
			
		||||
@@ -8,6 +9,8 @@ import { theme, ThemeProvider } from '../style/theme';
 | 
			
		||||
import { ZeroExInstantContainer } from './zero_ex_instant_container';
 | 
			
		||||
 | 
			
		||||
fonts.include();
 | 
			
		||||
// tslint:disable-next-line:no-floating-promises
 | 
			
		||||
asyncData.fetchAndDispatchToStore();
 | 
			
		||||
 | 
			
		||||
export interface ZeroExInstantProps {}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,21 @@
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { LatestBuyQuoteOrderDetails } from '../containers/latest_buy_quote_order_details';
 | 
			
		||||
import { LatestError } from '../containers/latest_error';
 | 
			
		||||
import { SelectedAssetBuyButton } from '../containers/selected_asset_buy_button';
 | 
			
		||||
import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
 | 
			
		||||
import { BuyButton } from './buy_button';
 | 
			
		||||
import { InstantHeading } from './instant_heading';
 | 
			
		||||
import { OrderDetails } from './order_details';
 | 
			
		||||
import { Container, Flex } from './ui';
 | 
			
		||||
 | 
			
		||||
export interface ZeroExInstantContainerProps {}
 | 
			
		||||
 | 
			
		||||
export const ZeroExInstantContainer: React.StatelessComponent<ZeroExInstantContainerProps> = props => (
 | 
			
		||||
    <Container width="350px">
 | 
			
		||||
        <Container zIndex={1} position="relative">
 | 
			
		||||
            <LatestError />
 | 
			
		||||
        </Container>
 | 
			
		||||
        <Container
 | 
			
		||||
            zIndex={2}
 | 
			
		||||
            position="relative"
 | 
			
		||||
@@ -19,9 +24,9 @@ export const ZeroExInstantContainer: React.StatelessComponent<ZeroExInstantConta
 | 
			
		||||
            hasBoxShadow={true}
 | 
			
		||||
        >
 | 
			
		||||
            <Flex direction="column" justify="flex-start">
 | 
			
		||||
                <InstantHeading />
 | 
			
		||||
                <OrderDetails />
 | 
			
		||||
                <BuyButton />
 | 
			
		||||
                <SelectedAssetInstantHeading />
 | 
			
		||||
                <LatestBuyQuoteOrderDetails />
 | 
			
		||||
                <SelectedAssetBuyButton />
 | 
			
		||||
            </Flex>
 | 
			
		||||
        </Container>
 | 
			
		||||
    </Container>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								packages/instant/src/constants.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								packages/instant/src/constants.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
export const BIG_NUMBER_ZERO = new BigNumber(0);
 | 
			
		||||
export const sraApiUrl = 'https://api.radarrelay.com/0x/v2/';
 | 
			
		||||
export const zrxAssetData = '0xf47261b0000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498';
 | 
			
		||||
export const zrxDecimals = 18;
 | 
			
		||||
export const ethDecimals = 18;
 | 
			
		||||
@@ -0,0 +1,27 @@
 | 
			
		||||
import { BuyQuoteInfo } from '@0xproject/asset-buyer';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import { oc } from 'ts-optchain';
 | 
			
		||||
 | 
			
		||||
import { State } from '../redux/reducer';
 | 
			
		||||
 | 
			
		||||
import { OrderDetails } from '../components/order_details';
 | 
			
		||||
 | 
			
		||||
export interface LatestBuyQuoteOrderDetailsProps {}
 | 
			
		||||
 | 
			
		||||
interface ConnectedState {
 | 
			
		||||
    buyQuoteInfo?: BuyQuoteInfo;
 | 
			
		||||
    ethUsdPrice?: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = (state: State, _ownProps: LatestBuyQuoteOrderDetailsProps): ConnectedState => ({
 | 
			
		||||
    // use the worst case quote info
 | 
			
		||||
    buyQuoteInfo: oc(state).latestBuyQuote.worstCaseQuoteInfo(),
 | 
			
		||||
    ethUsdPrice: state.ethUsdPrice,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const LatestBuyQuoteOrderDetails: React.ComponentClass<LatestBuyQuoteOrderDetailsProps> = connect(
 | 
			
		||||
    mapStateToProps,
 | 
			
		||||
)(OrderDetails);
 | 
			
		||||
							
								
								
									
										35
									
								
								packages/instant/src/containers/latest_error.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								packages/instant/src/containers/latest_error.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
 | 
			
		||||
import { SlidingError } from '../components/sliding_error';
 | 
			
		||||
import { LatestErrorDisplay, State } from '../redux/reducer';
 | 
			
		||||
import { errorUtil } from '../util/error';
 | 
			
		||||
 | 
			
		||||
export interface LatestErrorComponentProps {
 | 
			
		||||
    assetData?: string;
 | 
			
		||||
    latestError?: any;
 | 
			
		||||
    slidingDirection: 'down' | 'up';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const LatestErrorComponent: React.StatelessComponent<LatestErrorComponentProps> = props => {
 | 
			
		||||
    if (!props.latestError) {
 | 
			
		||||
        return <div />;
 | 
			
		||||
    }
 | 
			
		||||
    const { icon, message } = errorUtil.errorDescription(props.latestError, props.assetData);
 | 
			
		||||
    return <SlidingError direction={props.slidingDirection} icon={icon} message={message} />;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface ConnectedState {
 | 
			
		||||
    assetData?: string;
 | 
			
		||||
    latestError?: any;
 | 
			
		||||
    slidingDirection: 'down' | 'up';
 | 
			
		||||
}
 | 
			
		||||
export interface LatestErrorProps {}
 | 
			
		||||
const mapStateToProps = (state: State, _ownProps: LatestErrorProps): ConnectedState => ({
 | 
			
		||||
    assetData: state.selectedAssetData,
 | 
			
		||||
    latestError: state.latestError,
 | 
			
		||||
    slidingDirection: state.latestErrorDisplay === LatestErrorDisplay.Present ? 'up' : 'down',
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const LatestError = connect(mapStateToProps)(LatestErrorComponent);
 | 
			
		||||
@@ -0,0 +1,89 @@
 | 
			
		||||
import { BuyQuote } from '@0xproject/asset-buyer';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import { Dispatch } from 'redux';
 | 
			
		||||
 | 
			
		||||
import { zrxDecimals } from '../constants';
 | 
			
		||||
import { Action, actions } from '../redux/actions';
 | 
			
		||||
import { State } from '../redux/reducer';
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { AsyncProcessState } from '../types';
 | 
			
		||||
import { assetBuyer } from '../util/asset_buyer';
 | 
			
		||||
import { errorUtil } from '../util/error';
 | 
			
		||||
 | 
			
		||||
import { AssetAmountInput } from '../components/asset_amount_input';
 | 
			
		||||
 | 
			
		||||
export interface SelectedAssetAmountInputProps {
 | 
			
		||||
    fontColor?: ColorOption;
 | 
			
		||||
    fontSize?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface ConnectedState {
 | 
			
		||||
    value?: BigNumber;
 | 
			
		||||
    assetData?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface ConnectedDispatch {
 | 
			
		||||
    onChange: (value?: BigNumber, assetData?: string) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = (state: State, _ownProps: SelectedAssetAmountInputProps): ConnectedState => ({
 | 
			
		||||
    value: state.selectedAssetAmount,
 | 
			
		||||
    assetData: state.selectedAssetData,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const updateBuyQuoteAsync = async (
 | 
			
		||||
    dispatch: Dispatch<Action>,
 | 
			
		||||
    assetData: string,
 | 
			
		||||
    assetAmount: BigNumber,
 | 
			
		||||
): Promise<void> => {
 | 
			
		||||
    // get a new buy quote.
 | 
			
		||||
    const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, zrxDecimals);
 | 
			
		||||
 | 
			
		||||
    // mark quote as pending
 | 
			
		||||
    dispatch(actions.updateBuyQuoteStatePending());
 | 
			
		||||
 | 
			
		||||
    let newBuyQuote: BuyQuote | undefined;
 | 
			
		||||
    try {
 | 
			
		||||
        newBuyQuote = await assetBuyer.getBuyQuoteAsync(assetData, baseUnitValue);
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
        dispatch(actions.updateBuyQuoteStateFailure());
 | 
			
		||||
        errorUtil.errorFlasher.flashNewError(dispatch, error);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // We have a successful new buy quote
 | 
			
		||||
    errorUtil.errorFlasher.clearError(dispatch);
 | 
			
		||||
    // invalidate the last buy quote.
 | 
			
		||||
    dispatch(actions.updateLatestBuyQuote(newBuyQuote));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const debouncedUpdateBuyQuoteAsync = _.debounce(updateBuyQuoteAsync, 200, { trailing: true });
 | 
			
		||||
 | 
			
		||||
const mapDispatchToProps = (
 | 
			
		||||
    dispatch: Dispatch<Action>,
 | 
			
		||||
    _ownProps: SelectedAssetAmountInputProps,
 | 
			
		||||
): ConnectedDispatch => ({
 | 
			
		||||
    onChange: (value, assetData) => {
 | 
			
		||||
        // Update the input
 | 
			
		||||
        dispatch(actions.updateSelectedAssetAmount(value));
 | 
			
		||||
        // invalidate the last buy quote.
 | 
			
		||||
        dispatch(actions.updateLatestBuyQuote(undefined));
 | 
			
		||||
        // reset our buy state
 | 
			
		||||
        dispatch(actions.updatebuyOrderState(AsyncProcessState.NONE));
 | 
			
		||||
 | 
			
		||||
        if (!_.isUndefined(value) && !_.isUndefined(assetData)) {
 | 
			
		||||
            // even if it's debounced, give them the illusion it's loading
 | 
			
		||||
            dispatch(actions.updateBuyQuoteStatePending());
 | 
			
		||||
            // tslint:disable-next-line:no-floating-promises
 | 
			
		||||
            debouncedUpdateBuyQuoteAsync(dispatch, assetData, value);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const SelectedAssetAmountInput: React.ComponentClass<SelectedAssetAmountInputProps> = connect(
 | 
			
		||||
    mapStateToProps,
 | 
			
		||||
    mapDispatchToProps,
 | 
			
		||||
)(AssetAmountInput);
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import { Dispatch } from 'redux';
 | 
			
		||||
 | 
			
		||||
import { State } from '../redux/reducer';
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { Action, ActionTypes } from '../types';
 | 
			
		||||
 | 
			
		||||
import { AmountInput } from '../components/amount_input';
 | 
			
		||||
 | 
			
		||||
export interface SelectedAssetAmountInputProps {
 | 
			
		||||
    fontColor?: ColorOption;
 | 
			
		||||
    fontSize?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface ConnectedState {
 | 
			
		||||
    value?: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface ConnectedDispatch {
 | 
			
		||||
    onChange?: (value?: BigNumber) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = (state: State, _ownProps: SelectedAssetAmountInputProps): ConnectedState => ({
 | 
			
		||||
    value: state.selectedAssetAmount,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const mapDispatchToProps = (dispatch: Dispatch<Action>): ConnectedDispatch => ({
 | 
			
		||||
    onChange: value => dispatch({ type: ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, data: value }),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const SelectedAssetAmountInput: React.ComponentClass<SelectedAssetAmountInputProps> = connect(
 | 
			
		||||
    mapStateToProps,
 | 
			
		||||
    mapDispatchToProps,
 | 
			
		||||
)(AmountInput);
 | 
			
		||||
							
								
								
									
										55
									
								
								packages/instant/src/containers/selected_asset_buy_button.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								packages/instant/src/containers/selected_asset_buy_button.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
import { BuyQuote } from '@0xproject/asset-buyer';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import { Dispatch } from 'redux';
 | 
			
		||||
 | 
			
		||||
import { Action, actions } from '../redux/actions';
 | 
			
		||||
import { State } from '../redux/reducer';
 | 
			
		||||
import { AsyncProcessState } from '../types';
 | 
			
		||||
 | 
			
		||||
import { BuyButton } from '../components/buy_button';
 | 
			
		||||
 | 
			
		||||
export interface SelectedAssetBuyButtonProps {}
 | 
			
		||||
 | 
			
		||||
interface ConnectedState {
 | 
			
		||||
    text: string;
 | 
			
		||||
    buyQuote?: BuyQuote;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface ConnectedDispatch {
 | 
			
		||||
    onClick: (buyQuote: BuyQuote) => void;
 | 
			
		||||
    onBuySuccess: (buyQuote: BuyQuote) => void;
 | 
			
		||||
    onBuyFailure: (buyQuote: BuyQuote) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const textForState = (state: AsyncProcessState): string => {
 | 
			
		||||
    switch (state) {
 | 
			
		||||
        case AsyncProcessState.NONE:
 | 
			
		||||
            return 'Buy';
 | 
			
		||||
        case AsyncProcessState.PENDING:
 | 
			
		||||
            return '...Loading';
 | 
			
		||||
        case AsyncProcessState.SUCCESS:
 | 
			
		||||
            return 'Success!';
 | 
			
		||||
        case AsyncProcessState.FAILURE:
 | 
			
		||||
            return 'Failed';
 | 
			
		||||
        default:
 | 
			
		||||
            return 'Buy';
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyButtonProps): ConnectedState => ({
 | 
			
		||||
    text: textForState(state.buyOrderState),
 | 
			
		||||
    buyQuote: state.latestBuyQuote,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const mapDispatchToProps = (dispatch: Dispatch<Action>, ownProps: SelectedAssetBuyButtonProps): ConnectedDispatch => ({
 | 
			
		||||
    onClick: buyQuote => dispatch(actions.updatebuyOrderState(AsyncProcessState.PENDING)),
 | 
			
		||||
    onBuySuccess: buyQuote => dispatch(actions.updatebuyOrderState(AsyncProcessState.SUCCESS)),
 | 
			
		||||
    onBuyFailure: buyQuote => dispatch(actions.updatebuyOrderState(AsyncProcessState.FAILURE)),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const SelectedAssetBuyButton: React.ComponentClass<SelectedAssetBuyButtonProps> = connect(
 | 
			
		||||
    mapStateToProps,
 | 
			
		||||
    mapDispatchToProps,
 | 
			
		||||
)(BuyButton);
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import { oc } from 'ts-optchain';
 | 
			
		||||
 | 
			
		||||
import { State } from '../redux/reducer';
 | 
			
		||||
import { AsyncProcessState } from '../types';
 | 
			
		||||
 | 
			
		||||
import { InstantHeading } from '../components/instant_heading';
 | 
			
		||||
 | 
			
		||||
export interface InstantHeadingProps {}
 | 
			
		||||
 | 
			
		||||
interface ConnectedState {
 | 
			
		||||
    selectedAssetAmount?: BigNumber;
 | 
			
		||||
    totalEthBaseAmount?: BigNumber;
 | 
			
		||||
    ethUsdPrice?: BigNumber;
 | 
			
		||||
    quoteState: AsyncProcessState;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = (state: State, _ownProps: InstantHeadingProps): ConnectedState => ({
 | 
			
		||||
    selectedAssetAmount: state.selectedAssetAmount,
 | 
			
		||||
    totalEthBaseAmount: oc(state).latestBuyQuote.worstCaseQuoteInfo.totalEthAmount(),
 | 
			
		||||
    ethUsdPrice: state.ethUsdPrice,
 | 
			
		||||
    quoteState: state.quoteState,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const SelectedAssetInstantHeading: React.ComponentClass<InstantHeadingProps> = connect(mapStateToProps)(
 | 
			
		||||
    InstantHeading,
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										15
									
								
								packages/instant/src/data/asset_meta_data.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								packages/instant/src/data/asset_meta_data.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
import { AssetProxyId, ObjectMap } from '@0xproject/types';
 | 
			
		||||
 | 
			
		||||
import { zrxAssetData } from '../constants';
 | 
			
		||||
import { AssetMetaData } from '../types';
 | 
			
		||||
 | 
			
		||||
// Map from assetData string to AssetMetaData object
 | 
			
		||||
// TODO: import this from somewhere else.
 | 
			
		||||
export const assetMetaData: ObjectMap<AssetMetaData> = {
 | 
			
		||||
    [zrxAssetData]: {
 | 
			
		||||
        assetProxyId: AssetProxyId.ERC20,
 | 
			
		||||
        decimals: 18,
 | 
			
		||||
        primaryColor: 'rgb(54, 50, 60)',
 | 
			
		||||
        symbol: 'zrx',
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										46
									
								
								packages/instant/src/redux/actions.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								packages/instant/src/redux/actions.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
import { BuyQuote } from '@0xproject/asset-buyer';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { ActionsUnion, AsyncProcessState } from '../types';
 | 
			
		||||
 | 
			
		||||
export interface PlainAction<T extends string> {
 | 
			
		||||
    type: T;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ActionWithPayload<T extends string, P> extends PlainAction<T> {
 | 
			
		||||
    data: P;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type Action = ActionsUnion<typeof actions>;
 | 
			
		||||
 | 
			
		||||
function createAction<T extends string>(type: T): PlainAction<T>;
 | 
			
		||||
function createAction<T extends string, P>(type: T, data: P): ActionWithPayload<T, P>;
 | 
			
		||||
function createAction<T extends string, P>(type: T, data?: P): PlainAction<T> | ActionWithPayload<T, P> {
 | 
			
		||||
    return _.isUndefined(data) ? { type } : { type, data };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum ActionTypes {
 | 
			
		||||
    UPDATE_ETH_USD_PRICE = 'UPDATE_ETH_USD_PRICE',
 | 
			
		||||
    UPDATE_SELECTED_ASSET_AMOUNT = 'UPDATE_SELECTED_ASSET_AMOUNT',
 | 
			
		||||
    UPDATE_SELECTED_ASSET_BUY_STATE = 'UPDATE_SELECTED_ASSET_BUY_STATE',
 | 
			
		||||
    UPDATE_LATEST_BUY_QUOTE = 'UPDATE_LATEST_BUY_QUOTE',
 | 
			
		||||
    UPDATE_BUY_QUOTE_STATE_PENDING = 'UPDATE_BUY_QUOTE_STATE_PENDING',
 | 
			
		||||
    UPDATE_BUY_QUOTE_STATE_FAILURE = 'UPDATE_BUY_QUOTE_STATE_FAILURE',
 | 
			
		||||
    SET_ERROR = 'SET_ERROR',
 | 
			
		||||
    HIDE_ERROR = 'HIDE_ERROR',
 | 
			
		||||
    CLEAR_ERROR = 'CLEAR_ERROR',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const actions = {
 | 
			
		||||
    updateEthUsdPrice: (price?: BigNumber) => createAction(ActionTypes.UPDATE_ETH_USD_PRICE, price),
 | 
			
		||||
    updateSelectedAssetAmount: (amount?: BigNumber) => createAction(ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, amount),
 | 
			
		||||
    updatebuyOrderState: (buyState: AsyncProcessState) =>
 | 
			
		||||
        createAction(ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE, buyState),
 | 
			
		||||
    updateLatestBuyQuote: (buyQuote?: BuyQuote) => createAction(ActionTypes.UPDATE_LATEST_BUY_QUOTE, buyQuote),
 | 
			
		||||
    updateBuyQuoteStatePending: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_PENDING),
 | 
			
		||||
    updateBuyQuoteStateFailure: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_FAILURE),
 | 
			
		||||
    setError: (error?: any) => createAction(ActionTypes.SET_ERROR, error),
 | 
			
		||||
    hideError: () => createAction(ActionTypes.HIDE_ERROR),
 | 
			
		||||
    clearError: () => createAction(ActionTypes.CLEAR_ERROR),
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/instant/src/redux/async_data.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/instant/src/redux/async_data.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
import { BIG_NUMBER_ZERO } from '../constants';
 | 
			
		||||
import { coinbaseApi } from '../util/coinbase_api';
 | 
			
		||||
 | 
			
		||||
import { ActionTypes } from './actions';
 | 
			
		||||
 | 
			
		||||
import { store } from './store';
 | 
			
		||||
 | 
			
		||||
export const asyncData = {
 | 
			
		||||
    fetchAndDispatchToStore: async () => {
 | 
			
		||||
        let ethUsdPrice = BIG_NUMBER_ZERO;
 | 
			
		||||
        try {
 | 
			
		||||
            ethUsdPrice = await coinbaseApi.getEthUsdPrice();
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            // ignore
 | 
			
		||||
        } finally {
 | 
			
		||||
            store.dispatch({
 | 
			
		||||
                type: ActionTypes.UPDATE_ETH_USD_PRICE,
 | 
			
		||||
                data: ethUsdPrice,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
@@ -1,16 +1,37 @@
 | 
			
		||||
import { BuyQuote } from '@0xproject/asset-buyer';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { Action, ActionTypes } from '../types';
 | 
			
		||||
import { zrxAssetData } from '../constants';
 | 
			
		||||
import { AsyncProcessState } from '../types';
 | 
			
		||||
 | 
			
		||||
import { Action, ActionTypes } from './actions';
 | 
			
		||||
 | 
			
		||||
export enum LatestErrorDisplay {
 | 
			
		||||
    Present,
 | 
			
		||||
    Hidden,
 | 
			
		||||
}
 | 
			
		||||
export interface State {
 | 
			
		||||
    ethUsdPrice?: string;
 | 
			
		||||
    selectedAssetData?: string;
 | 
			
		||||
    selectedAssetAmount?: BigNumber;
 | 
			
		||||
    buyOrderState: AsyncProcessState;
 | 
			
		||||
    ethUsdPrice?: BigNumber;
 | 
			
		||||
    latestBuyQuote?: BuyQuote;
 | 
			
		||||
    quoteState: AsyncProcessState;
 | 
			
		||||
    latestError?: any;
 | 
			
		||||
    latestErrorDisplay: LatestErrorDisplay;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const INITIAL_STATE: State = {
 | 
			
		||||
    ethUsdPrice: undefined,
 | 
			
		||||
    // TODO: Remove hardcoded zrxAssetData
 | 
			
		||||
    selectedAssetData: zrxAssetData,
 | 
			
		||||
    selectedAssetAmount: undefined,
 | 
			
		||||
    buyOrderState: AsyncProcessState.NONE,
 | 
			
		||||
    ethUsdPrice: undefined,
 | 
			
		||||
    latestBuyQuote: undefined,
 | 
			
		||||
    latestError: undefined,
 | 
			
		||||
    latestErrorDisplay: LatestErrorDisplay.Hidden,
 | 
			
		||||
    quoteState: AsyncProcessState.NONE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const reducer = (state: State = INITIAL_STATE, action: Action): State => {
 | 
			
		||||
@@ -25,6 +46,46 @@ export const reducer = (state: State = INITIAL_STATE, action: Action): State =>
 | 
			
		||||
                ...state,
 | 
			
		||||
                selectedAssetAmount: action.data,
 | 
			
		||||
            };
 | 
			
		||||
        case ActionTypes.UPDATE_LATEST_BUY_QUOTE:
 | 
			
		||||
            return {
 | 
			
		||||
                ...state,
 | 
			
		||||
                latestBuyQuote: action.data,
 | 
			
		||||
                quoteState: AsyncProcessState.SUCCESS,
 | 
			
		||||
            };
 | 
			
		||||
        case ActionTypes.UPDATE_BUY_QUOTE_STATE_PENDING:
 | 
			
		||||
            return {
 | 
			
		||||
                ...state,
 | 
			
		||||
                latestBuyQuote: undefined,
 | 
			
		||||
                quoteState: AsyncProcessState.PENDING,
 | 
			
		||||
            };
 | 
			
		||||
        case ActionTypes.UPDATE_BUY_QUOTE_STATE_FAILURE:
 | 
			
		||||
            return {
 | 
			
		||||
                ...state,
 | 
			
		||||
                latestBuyQuote: undefined,
 | 
			
		||||
                quoteState: AsyncProcessState.FAILURE,
 | 
			
		||||
            };
 | 
			
		||||
        case ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE:
 | 
			
		||||
            return {
 | 
			
		||||
                ...state,
 | 
			
		||||
                buyOrderState: action.data,
 | 
			
		||||
            };
 | 
			
		||||
        case ActionTypes.SET_ERROR:
 | 
			
		||||
            return {
 | 
			
		||||
                ...state,
 | 
			
		||||
                latestError: action.data,
 | 
			
		||||
                latestErrorDisplay: LatestErrorDisplay.Present,
 | 
			
		||||
            };
 | 
			
		||||
        case ActionTypes.HIDE_ERROR:
 | 
			
		||||
            return {
 | 
			
		||||
                ...state,
 | 
			
		||||
                latestErrorDisplay: LatestErrorDisplay.Hidden,
 | 
			
		||||
            };
 | 
			
		||||
        case ActionTypes.CLEAR_ERROR:
 | 
			
		||||
            return {
 | 
			
		||||
                ...state,
 | 
			
		||||
                latestError: undefined,
 | 
			
		||||
                latestErrorDisplay: LatestErrorDisplay.Hidden,
 | 
			
		||||
            };
 | 
			
		||||
        default:
 | 
			
		||||
            return state;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import { createStore, Store as ReduxStore } from 'redux';
 | 
			
		||||
import { devToolsEnhancer } from 'redux-devtools-extension/developmentOnly';
 | 
			
		||||
 | 
			
		||||
import { reducer, State } from './reducer';
 | 
			
		||||
 | 
			
		||||
export const store: ReduxStore<State> = createStore(reducer);
 | 
			
		||||
export const store: ReduxStore<State> = createStore(reducer, devToolsEnhancer({}));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,33 @@
 | 
			
		||||
export enum ActionTypes {
 | 
			
		||||
    UPDATE_ETH_USD_PRICE,
 | 
			
		||||
    UPDATE_SELECTED_ASSET_AMOUNT,
 | 
			
		||||
import { AssetProxyId, ObjectMap } from '@0xproject/types';
 | 
			
		||||
 | 
			
		||||
// Reusable
 | 
			
		||||
export enum AsyncProcessState {
 | 
			
		||||
    NONE = 'None',
 | 
			
		||||
    PENDING = 'Pending',
 | 
			
		||||
    SUCCESS = 'Success',
 | 
			
		||||
    FAILURE = 'Failure',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface Action {
 | 
			
		||||
    type: ActionTypes;
 | 
			
		||||
    data?: any;
 | 
			
		||||
export type FunctionType = (...args: any[]) => any;
 | 
			
		||||
export type ActionCreatorsMapObject = ObjectMap<FunctionType>;
 | 
			
		||||
export type ActionsUnion<A extends ActionCreatorsMapObject> = ReturnType<A[keyof A]>;
 | 
			
		||||
 | 
			
		||||
export interface ERC20AssetMetaData {
 | 
			
		||||
    assetProxyId: AssetProxyId.ERC20;
 | 
			
		||||
    decimals: number;
 | 
			
		||||
    primaryColor?: string;
 | 
			
		||||
    symbol: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ERC721AssetMetaData {
 | 
			
		||||
    assetProxyId: AssetProxyId.ERC721;
 | 
			
		||||
    name: string;
 | 
			
		||||
    primaryColor?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type AssetMetaData = ERC20AssetMetaData | ERC721AssetMetaData;
 | 
			
		||||
 | 
			
		||||
export enum Network {
 | 
			
		||||
    Kovan = 42,
 | 
			
		||||
    Mainnet = 1,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								packages/instant/src/util/asset_buyer.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								packages/instant/src/util/asset_buyer.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
import { AssetBuyer } from '@0xproject/asset-buyer';
 | 
			
		||||
 | 
			
		||||
import { sraApiUrl } from '../constants';
 | 
			
		||||
 | 
			
		||||
import { getProvider } from './provider';
 | 
			
		||||
 | 
			
		||||
const provider = getProvider();
 | 
			
		||||
 | 
			
		||||
export const assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(provider, sraApiUrl);
 | 
			
		||||
							
								
								
									
										21
									
								
								packages/instant/src/util/asset_data.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								packages/instant/src/util/asset_data.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { AssetProxyId } from '@0xproject/types';
 | 
			
		||||
 | 
			
		||||
import { assetMetaData } from '../data/asset_meta_data';
 | 
			
		||||
 | 
			
		||||
export const assetDataUtil = {
 | 
			
		||||
    bestNameForAsset: (assetData: string | undefined, defaultString: string) => {
 | 
			
		||||
        if (_.isUndefined(assetData)) {
 | 
			
		||||
            return defaultString;
 | 
			
		||||
        }
 | 
			
		||||
        const metaData = assetMetaData[assetData];
 | 
			
		||||
        if (_.isUndefined(metaData)) {
 | 
			
		||||
            return defaultString;
 | 
			
		||||
        }
 | 
			
		||||
        if (metaData.assetProxyId === AssetProxyId.ERC20) {
 | 
			
		||||
            return metaData.symbol.toUpperCase();
 | 
			
		||||
        }
 | 
			
		||||
        return defaultString;
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										10
									
								
								packages/instant/src/util/coinbase_api.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								packages/instant/src/util/coinbase_api.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
 | 
			
		||||
const baseEndpoint = 'https://api.coinbase.com/v2';
 | 
			
		||||
export const coinbaseApi = {
 | 
			
		||||
    getEthUsdPrice: async (): Promise<BigNumber> => {
 | 
			
		||||
        const res = await fetch(`${baseEndpoint}/prices/ETH-USD/buy`);
 | 
			
		||||
        const resJson = await res.json();
 | 
			
		||||
        return new BigNumber(resJson.data.amount);
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										62
									
								
								packages/instant/src/util/error.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								packages/instant/src/util/error.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
import { AssetBuyerError } from '@0xproject/asset-buyer';
 | 
			
		||||
import { Dispatch } from 'redux';
 | 
			
		||||
 | 
			
		||||
import { Action, actions } from '../redux/actions';
 | 
			
		||||
import { assetDataUtil } from '../util/asset_data';
 | 
			
		||||
 | 
			
		||||
class ErrorFlasher {
 | 
			
		||||
    private _timeoutId?: number;
 | 
			
		||||
    public flashNewError(dispatch: Dispatch<Action>, error: any, delayMs: number = 7000): void {
 | 
			
		||||
        this._clearTimeout();
 | 
			
		||||
 | 
			
		||||
        // dispatch new message
 | 
			
		||||
        dispatch(actions.setError(error));
 | 
			
		||||
 | 
			
		||||
        this._timeoutId = window.setTimeout(() => {
 | 
			
		||||
            dispatch(actions.hideError());
 | 
			
		||||
        }, delayMs);
 | 
			
		||||
    }
 | 
			
		||||
    public clearError(dispatch: Dispatch<Action>): void {
 | 
			
		||||
        this._clearTimeout();
 | 
			
		||||
        dispatch(actions.hideError());
 | 
			
		||||
    }
 | 
			
		||||
    private _clearTimeout(): void {
 | 
			
		||||
        if (this._timeoutId) {
 | 
			
		||||
            window.clearTimeout(this._timeoutId);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const humanReadableMessageForError = (error: Error, assetData?: string): string | undefined => {
 | 
			
		||||
    const hasInsufficientLiquidity =
 | 
			
		||||
        error.message === AssetBuyerError.InsufficientAssetLiquidity ||
 | 
			
		||||
        error.message === AssetBuyerError.InsufficientZrxLiquidity;
 | 
			
		||||
    if (hasInsufficientLiquidity) {
 | 
			
		||||
        const assetName = assetDataUtil.bestNameForAsset(assetData, 'of this asset');
 | 
			
		||||
        return `Not enough ${assetName} available`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
        error.message === AssetBuyerError.StandardRelayerApiError ||
 | 
			
		||||
        error.message.startsWith(AssetBuyerError.AssetUnavailable)
 | 
			
		||||
    ) {
 | 
			
		||||
        const assetName = assetDataUtil.bestNameForAsset(assetData, 'This asset');
 | 
			
		||||
        return `${assetName} is currently unavailable`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return undefined;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const errorUtil = {
 | 
			
		||||
    errorFlasher: new ErrorFlasher(),
 | 
			
		||||
    errorDescription: (error?: any, assetData?: string): { icon: string; message: string } => {
 | 
			
		||||
        let bestMessage: string | undefined;
 | 
			
		||||
        if (error instanceof Error) {
 | 
			
		||||
            bestMessage = humanReadableMessageForError(error, assetData);
 | 
			
		||||
        }
 | 
			
		||||
        return {
 | 
			
		||||
            icon: '😢',
 | 
			
		||||
            message: bestMessage || 'Something went wrong...',
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										53
									
								
								packages/instant/src/util/format.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								packages/instant/src/util/format.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { ethDecimals } from '../constants';
 | 
			
		||||
 | 
			
		||||
export const format = {
 | 
			
		||||
    ethBaseAmount: (
 | 
			
		||||
        ethBaseAmount?: BigNumber,
 | 
			
		||||
        decimalPlaces: number = 4,
 | 
			
		||||
        defaultText: React.ReactNode = '0 ETH',
 | 
			
		||||
    ): React.ReactNode => {
 | 
			
		||||
        if (_.isUndefined(ethBaseAmount)) {
 | 
			
		||||
            return defaultText;
 | 
			
		||||
        }
 | 
			
		||||
        const ethUnitAmount = Web3Wrapper.toUnitAmount(ethBaseAmount, ethDecimals);
 | 
			
		||||
        return format.ethUnitAmount(ethUnitAmount, decimalPlaces);
 | 
			
		||||
    },
 | 
			
		||||
    ethUnitAmount: (
 | 
			
		||||
        ethUnitAmount?: BigNumber,
 | 
			
		||||
        decimalPlaces: number = 4,
 | 
			
		||||
        defaultText: React.ReactNode = '0 ETH',
 | 
			
		||||
    ): React.ReactNode => {
 | 
			
		||||
        if (_.isUndefined(ethUnitAmount)) {
 | 
			
		||||
            return defaultText;
 | 
			
		||||
        }
 | 
			
		||||
        const roundedAmount = ethUnitAmount.round(decimalPlaces);
 | 
			
		||||
        return `${roundedAmount} ETH`;
 | 
			
		||||
    },
 | 
			
		||||
    ethBaseAmountInUsd: (
 | 
			
		||||
        ethBaseAmount?: BigNumber,
 | 
			
		||||
        ethUsdPrice?: BigNumber,
 | 
			
		||||
        decimalPlaces: number = 2,
 | 
			
		||||
        defaultText: React.ReactNode = '$0.00',
 | 
			
		||||
    ): React.ReactNode => {
 | 
			
		||||
        if (_.isUndefined(ethBaseAmount) || _.isUndefined(ethUsdPrice)) {
 | 
			
		||||
            return defaultText;
 | 
			
		||||
        }
 | 
			
		||||
        const ethUnitAmount = Web3Wrapper.toUnitAmount(ethBaseAmount, ethDecimals);
 | 
			
		||||
        return format.ethUnitAmountInUsd(ethUnitAmount, ethUsdPrice, decimalPlaces);
 | 
			
		||||
    },
 | 
			
		||||
    ethUnitAmountInUsd: (
 | 
			
		||||
        ethUnitAmount?: BigNumber,
 | 
			
		||||
        ethUsdPrice?: BigNumber,
 | 
			
		||||
        decimalPlaces: number = 2,
 | 
			
		||||
        defaultText: React.ReactNode = '$0.00',
 | 
			
		||||
    ): React.ReactNode => {
 | 
			
		||||
        if (_.isUndefined(ethUnitAmount) || _.isUndefined(ethUsdPrice)) {
 | 
			
		||||
            return defaultText;
 | 
			
		||||
        }
 | 
			
		||||
        return `$${ethUnitAmount.mul(ethUsdPrice).toFixed(decimalPlaces)}`;
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										12
									
								
								packages/instant/src/util/provider.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								packages/instant/src/util/provider.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
import { Provider } from 'ethereum-types';
 | 
			
		||||
 | 
			
		||||
export const getProvider = (): Provider => {
 | 
			
		||||
    const injectedWeb3 = (window as any).web3 || undefined;
 | 
			
		||||
    try {
 | 
			
		||||
        // Use MetaMask/Mist provider
 | 
			
		||||
        return injectedWeb3.currentProvider;
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
        // Throws when user doesn't have MetaMask/Mist running
 | 
			
		||||
        throw new Error(`No injected web3 found: ${err}`);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										5
									
								
								packages/instant/src/util/util.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/instant/src/util/util.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
export const util = {
 | 
			
		||||
    boundNoop: _.noop.bind(_),
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										5
									
								
								packages/instant/src/util/web3_wrapper.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/instant/src/util/web3_wrapper.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
 | 
			
		||||
import { getProvider } from './provider';
 | 
			
		||||
 | 
			
		||||
export const web3Wrapper = new Web3Wrapper(getProvider());
 | 
			
		||||
@@ -4,10 +4,12 @@ import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
configure({ adapter: new Adapter() });
 | 
			
		||||
 | 
			
		||||
import { ZeroExInstant } from '../../src';
 | 
			
		||||
 | 
			
		||||
describe('<ZeroExInstant />', () => {
 | 
			
		||||
    it('shallow renders without crashing', () => {
 | 
			
		||||
        shallow(<ZeroExInstant />);
 | 
			
		||||
// TODO: Write non-trivial tests.
 | 
			
		||||
// At time of writing we cannot render ZeroExInstant
 | 
			
		||||
// because we are looking for a provider on window.
 | 
			
		||||
// But in the future it will be dependency injected.
 | 
			
		||||
describe('<Test />', () => {
 | 
			
		||||
    it('runs a test', () => {
 | 
			
		||||
        shallow(<div />);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								packages/instant/test/util/asset_data.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								packages/instant/test/util/asset_data.test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
import { assetDataUtil } from '../../src/util/asset_data';
 | 
			
		||||
 | 
			
		||||
const ZRX_ASSET_DATA = '0xf47261b0000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498';
 | 
			
		||||
 | 
			
		||||
describe('assetDataUtil', () => {
 | 
			
		||||
    describe('bestNameForAsset', () => {
 | 
			
		||||
        it('should return default string if assetData is undefined', () => {
 | 
			
		||||
            expect(assetDataUtil.bestNameForAsset(undefined, 'xyz')).toEqual('xyz');
 | 
			
		||||
        });
 | 
			
		||||
        it('should return default string if assetData isnt found', () => {
 | 
			
		||||
            expect(assetDataUtil.bestNameForAsset('fake', 'mah default')).toEqual('mah default');
 | 
			
		||||
        });
 | 
			
		||||
        it('should return ZRX for ZRX assetData', () => {
 | 
			
		||||
            expect(assetDataUtil.bestNameForAsset(ZRX_ASSET_DATA, 'mah default')).toEqual('ZRX');
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										48
									
								
								packages/instant/test/util/error.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								packages/instant/test/util/error.test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
import { AssetBuyerError } from '@0xproject/asset-buyer';
 | 
			
		||||
 | 
			
		||||
import { errorUtil } from '../../src/util/error';
 | 
			
		||||
 | 
			
		||||
const ZRX_ASSET_DATA = '0xf47261b0000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498';
 | 
			
		||||
 | 
			
		||||
describe('errorUtil', () => {
 | 
			
		||||
    describe('errorFlasher', () => {
 | 
			
		||||
        it('should return error and asset name for InsufficientAssetLiquidity', () => {
 | 
			
		||||
            const insufficientAssetError = new Error(AssetBuyerError.InsufficientAssetLiquidity);
 | 
			
		||||
            expect(errorUtil.errorDescription(insufficientAssetError, ZRX_ASSET_DATA).message).toEqual(
 | 
			
		||||
                'Not enough ZRX available',
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('should return error default name for InsufficientAssetLiquidity', () => {
 | 
			
		||||
            const insufficientZrxError = new Error(AssetBuyerError.InsufficientZrxLiquidity);
 | 
			
		||||
            expect(errorUtil.errorDescription(insufficientZrxError).message).toEqual(
 | 
			
		||||
                'Not enough of this asset available',
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('should return asset name for InsufficientAssetLiquidity', () => {
 | 
			
		||||
            const insufficientZrxError = new Error(AssetBuyerError.InsufficientZrxLiquidity);
 | 
			
		||||
            expect(errorUtil.errorDescription(insufficientZrxError, ZRX_ASSET_DATA).message).toEqual(
 | 
			
		||||
                'Not enough ZRX available',
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('should return unavailable error and asset name for StandardRelayerApiError', () => {
 | 
			
		||||
            const standardRelayerError = new Error(AssetBuyerError.StandardRelayerApiError);
 | 
			
		||||
            expect(errorUtil.errorDescription(standardRelayerError, ZRX_ASSET_DATA).message).toEqual(
 | 
			
		||||
                'ZRX is currently unavailable',
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('should return error for AssetUnavailable error', () => {
 | 
			
		||||
            const assetUnavailableError = new Error(
 | 
			
		||||
                `${AssetBuyerError.AssetUnavailable}: For assetData ${ZRX_ASSET_DATA}`,
 | 
			
		||||
            );
 | 
			
		||||
            expect(errorUtil.errorDescription(assetUnavailableError, ZRX_ASSET_DATA).message).toEqual(
 | 
			
		||||
                'ZRX is currently unavailable',
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('should return default for AssetUnavailable error', () => {
 | 
			
		||||
            const assetUnavailableError = new Error(`${AssetBuyerError.AssetUnavailable}: For assetData xyz`);
 | 
			
		||||
            expect(errorUtil.errorDescription(assetUnavailableError, 'xyz').message).toEqual(
 | 
			
		||||
                'This asset is currently unavailable',
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										97
									
								
								packages/instant/test/util/format.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								packages/instant/test/util/format.test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
 | 
			
		||||
import { ethDecimals } from '../../src/constants';
 | 
			
		||||
import { format } from '../../src/util/format';
 | 
			
		||||
 | 
			
		||||
const BIG_NUMBER_ONE = new BigNumber(1);
 | 
			
		||||
const BIG_NUMBER_DECIMAL = new BigNumber(0.432414);
 | 
			
		||||
const BIG_NUMBER_IRRATIONAL = new BigNumber(5.3014059295032);
 | 
			
		||||
const ONE_ETH_IN_BASE_UNITS = Web3Wrapper.toBaseUnitAmount(BIG_NUMBER_ONE, ethDecimals);
 | 
			
		||||
const DECIMAL_ETH_IN_BASE_UNITS = Web3Wrapper.toBaseUnitAmount(BIG_NUMBER_DECIMAL, ethDecimals);
 | 
			
		||||
const IRRATIONAL_ETH_IN_BASE_UNITS = Web3Wrapper.toBaseUnitAmount(BIG_NUMBER_IRRATIONAL, ethDecimals);
 | 
			
		||||
const BIG_NUMBER_FAKE_ETH_USD_PRICE = new BigNumber(2.534);
 | 
			
		||||
 | 
			
		||||
describe('format', () => {
 | 
			
		||||
    describe('ethBaseAmount', () => {
 | 
			
		||||
        it('converts 1 ETH in base units to the string `1 ETH`', () => {
 | 
			
		||||
            expect(format.ethBaseAmount(ONE_ETH_IN_BASE_UNITS)).toBe('1 ETH');
 | 
			
		||||
        });
 | 
			
		||||
        it('converts .432414 ETH in base units to the string `.4324 ETH`', () => {
 | 
			
		||||
            expect(format.ethBaseAmount(DECIMAL_ETH_IN_BASE_UNITS)).toBe('0.4324 ETH');
 | 
			
		||||
        });
 | 
			
		||||
        it('converts 5.3014059295032 ETH in base units to the string `5.3014 ETH`', () => {
 | 
			
		||||
            expect(format.ethBaseAmount(IRRATIONAL_ETH_IN_BASE_UNITS)).toBe('5.3014 ETH');
 | 
			
		||||
        });
 | 
			
		||||
        it('returns defaultText param when ethBaseAmount is not defined', () => {
 | 
			
		||||
            const defaultText = 'defaultText';
 | 
			
		||||
            expect(format.ethBaseAmount(undefined, 4, defaultText)).toBe(defaultText);
 | 
			
		||||
        });
 | 
			
		||||
        it('it allows for configurable decimal places', () => {
 | 
			
		||||
            expect(format.ethBaseAmount(DECIMAL_ETH_IN_BASE_UNITS, 2)).toBe('0.43 ETH');
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('ethUnitAmount', () => {
 | 
			
		||||
        it('converts BigNumber(1) to the string `1 ETH`', () => {
 | 
			
		||||
            expect(format.ethUnitAmount(BIG_NUMBER_ONE)).toBe('1 ETH');
 | 
			
		||||
        });
 | 
			
		||||
        it('converts BigNumer(.432414) to the string `.4324 ETH`', () => {
 | 
			
		||||
            expect(format.ethUnitAmount(BIG_NUMBER_DECIMAL)).toBe('0.4324 ETH');
 | 
			
		||||
        });
 | 
			
		||||
        it('converts BigNumber(5.3014059295032) to the string `5.3014 ETH`', () => {
 | 
			
		||||
            expect(format.ethUnitAmount(BIG_NUMBER_IRRATIONAL)).toBe('5.3014 ETH');
 | 
			
		||||
        });
 | 
			
		||||
        it('returns defaultText param when ethUnitAmount is not defined', () => {
 | 
			
		||||
            const defaultText = 'defaultText';
 | 
			
		||||
            expect(format.ethUnitAmount(undefined, 4, defaultText)).toBe(defaultText);
 | 
			
		||||
            expect(format.ethUnitAmount(BIG_NUMBER_ONE, 4, defaultText)).toBe('1 ETH');
 | 
			
		||||
        });
 | 
			
		||||
        it('it allows for configurable decimal places', () => {
 | 
			
		||||
            expect(format.ethUnitAmount(BIG_NUMBER_DECIMAL, 2)).toBe('0.43 ETH');
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('ethBaseAmountInUsd', () => {
 | 
			
		||||
        it('correctly formats 1 ETH to usd according to some price', () => {
 | 
			
		||||
            expect(format.ethBaseAmountInUsd(ONE_ETH_IN_BASE_UNITS, BIG_NUMBER_FAKE_ETH_USD_PRICE)).toBe('$2.53');
 | 
			
		||||
        });
 | 
			
		||||
        it('correctly formats .432414 ETH to usd according to some price', () => {
 | 
			
		||||
            expect(format.ethBaseAmountInUsd(DECIMAL_ETH_IN_BASE_UNITS, BIG_NUMBER_FAKE_ETH_USD_PRICE)).toBe('$1.10');
 | 
			
		||||
        });
 | 
			
		||||
        it('correctly formats 5.3014059295032 ETH to usd according to some price', () => {
 | 
			
		||||
            expect(format.ethBaseAmountInUsd(IRRATIONAL_ETH_IN_BASE_UNITS, BIG_NUMBER_FAKE_ETH_USD_PRICE)).toBe(
 | 
			
		||||
                '$13.43',
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('returns defaultText param when ethBaseAmountInUsd or ethUsdPrice is not defined', () => {
 | 
			
		||||
            const defaultText = 'defaultText';
 | 
			
		||||
            expect(format.ethBaseAmountInUsd(undefined, undefined, 2, defaultText)).toBe(defaultText);
 | 
			
		||||
            expect(format.ethBaseAmountInUsd(BIG_NUMBER_ONE, undefined, 2, defaultText)).toBe(defaultText);
 | 
			
		||||
            expect(format.ethBaseAmountInUsd(undefined, BIG_NUMBER_ONE, 2, defaultText)).toBe(defaultText);
 | 
			
		||||
        });
 | 
			
		||||
        it('it allows for configurable decimal places', () => {
 | 
			
		||||
            expect(format.ethBaseAmountInUsd(DECIMAL_ETH_IN_BASE_UNITS, BIG_NUMBER_FAKE_ETH_USD_PRICE, 4)).toBe(
 | 
			
		||||
                '$1.0957',
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('ethUnitAmountInUsd', () => {
 | 
			
		||||
        it('correctly formats 1 ETH to usd according to some price', () => {
 | 
			
		||||
            expect(format.ethUnitAmountInUsd(BIG_NUMBER_ONE, BIG_NUMBER_FAKE_ETH_USD_PRICE)).toBe('$2.53');
 | 
			
		||||
        });
 | 
			
		||||
        it('correctly formats .432414 ETH to usd according to some price', () => {
 | 
			
		||||
            expect(format.ethUnitAmountInUsd(BIG_NUMBER_DECIMAL, BIG_NUMBER_FAKE_ETH_USD_PRICE)).toBe('$1.10');
 | 
			
		||||
        });
 | 
			
		||||
        it('correctly formats 5.3014059295032 ETH to usd according to some price', () => {
 | 
			
		||||
            expect(format.ethUnitAmountInUsd(BIG_NUMBER_IRRATIONAL, BIG_NUMBER_FAKE_ETH_USD_PRICE)).toBe('$13.43');
 | 
			
		||||
        });
 | 
			
		||||
        it('returns defaultText param when ethUnitAmountInUsd or ethUsdPrice is not defined', () => {
 | 
			
		||||
            const defaultText = 'defaultText';
 | 
			
		||||
            expect(format.ethUnitAmountInUsd(undefined, undefined, 2, defaultText)).toBe(defaultText);
 | 
			
		||||
            expect(format.ethUnitAmountInUsd(BIG_NUMBER_ONE, undefined, 2, defaultText)).toBe(defaultText);
 | 
			
		||||
            expect(format.ethUnitAmountInUsd(undefined, BIG_NUMBER_ONE, 2, defaultText)).toBe(defaultText);
 | 
			
		||||
        });
 | 
			
		||||
        it('it allows for configurable decimal places', () => {
 | 
			
		||||
            expect(format.ethUnitAmountInUsd(BIG_NUMBER_DECIMAL, BIG_NUMBER_FAKE_ETH_USD_PRICE, 4)).toBe('$1.0957');
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
@@ -1,4 +1,14 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "2.0.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note":
 | 
			
		||||
                    "Convert all schemas to JSON files so that they can be used with `json-schema` implemenations in other programming languages.",
 | 
			
		||||
                "pr": 1145
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1538693146,
 | 
			
		||||
        "version": "1.0.7",
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "build": "tsc -b",
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
        "lint": "tslint --project .",
 | 
			
		||||
        "lint": "tslint --project . --exclude **/schemas/**/*",
 | 
			
		||||
        "test": "yarn run_mocha",
 | 
			
		||||
        "rebuild_and_test": "run-s clean build test",
 | 
			
		||||
        "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
 | 
			
		||||
@@ -59,7 +59,7 @@
 | 
			
		||||
        "nyc": "^11.0.1",
 | 
			
		||||
        "shx": "^0.2.2",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typedoc": "0.12.0",
 | 
			
		||||
        "typedoc": "0.13.0",
 | 
			
		||||
        "typescript": "3.0.1"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								packages/json-schemas/schemas/address_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/json-schemas/schemas/address_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/addressSchema",
 | 
			
		||||
    "type": "string",
 | 
			
		||||
    "pattern": "^0x[0-9a-f]{40}$"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
export const addressSchema = {
 | 
			
		||||
    id: '/addressSchema',
 | 
			
		||||
    type: 'string',
 | 
			
		||||
    pattern: '^0x[0-9a-f]{40}$',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const hexSchema = {
 | 
			
		||||
    id: '/hexSchema',
 | 
			
		||||
    type: 'string',
 | 
			
		||||
    pattern: '^0x(([0-9a-f][0-9a-f])+)?$',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const numberSchema = {
 | 
			
		||||
    id: '/numberSchema',
 | 
			
		||||
    type: 'string',
 | 
			
		||||
    pattern: '^\\d+(\\.\\d+)?$',
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										11
									
								
								packages/json-schemas/schemas/block_param_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								packages/json-schemas/schemas/block_param_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/blockParamSchema",
 | 
			
		||||
    "oneOf": [
 | 
			
		||||
        {
 | 
			
		||||
            "type": "number"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "enum": ["latest", "earliest", "pending"]
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								packages/json-schemas/schemas/block_range_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packages/json-schemas/schemas/block_range_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/blockRangeSchema",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "fromBlock": { "$ref": "/blockParamSchema" },
 | 
			
		||||
        "toBlock": { "$ref": "/blockParamSchema" }
 | 
			
		||||
    },
 | 
			
		||||
    "type": "object"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
export const blockParamSchema = {
 | 
			
		||||
    id: '/blockParamSchema',
 | 
			
		||||
    oneOf: [
 | 
			
		||||
        {
 | 
			
		||||
            type: 'number',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            enum: ['latest', 'earliest', 'pending'],
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const blockRangeSchema = {
 | 
			
		||||
    id: '/blockRangeSchema',
 | 
			
		||||
    properties: {
 | 
			
		||||
        fromBlock: { $ref: '/blockParamSchema' },
 | 
			
		||||
        toBlock: { $ref: '/blockParamSchema' },
 | 
			
		||||
    },
 | 
			
		||||
    type: 'object',
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										27
									
								
								packages/json-schemas/schemas/call_data_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								packages/json-schemas/schemas/call_data_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/callDataSchema",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "from": { "$ref": "/addressSchema" },
 | 
			
		||||
        "to": { "$ref": "/addressSchema" },
 | 
			
		||||
        "value": {
 | 
			
		||||
            "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumber" }]
 | 
			
		||||
        },
 | 
			
		||||
        "gas": {
 | 
			
		||||
            "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumber" }]
 | 
			
		||||
        },
 | 
			
		||||
        "gasPrice": {
 | 
			
		||||
            "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumber" }]
 | 
			
		||||
        },
 | 
			
		||||
        "data": {
 | 
			
		||||
            "type": "string",
 | 
			
		||||
            "pattern": "^0x[0-9a-f]*$"
 | 
			
		||||
        },
 | 
			
		||||
        "nonce": {
 | 
			
		||||
            "type": "number",
 | 
			
		||||
            "minimum": 0
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "required": [],
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "additionalProperties": false
 | 
			
		||||
}
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
export const callDataSchema = {
 | 
			
		||||
    id: '/callDataSchema',
 | 
			
		||||
    properties: {
 | 
			
		||||
        from: { $ref: '/addressSchema' },
 | 
			
		||||
        to: { $ref: '/addressSchema' },
 | 
			
		||||
        value: {
 | 
			
		||||
            oneOf: [{ $ref: '/numberSchema' }, { $ref: '/jsNumber' }],
 | 
			
		||||
        },
 | 
			
		||||
        gas: {
 | 
			
		||||
            oneOf: [{ $ref: '/numberSchema' }, { $ref: '/jsNumber' }],
 | 
			
		||||
        },
 | 
			
		||||
        gasPrice: {
 | 
			
		||||
            oneOf: [{ $ref: '/numberSchema' }, { $ref: '/jsNumber' }],
 | 
			
		||||
        },
 | 
			
		||||
        data: {
 | 
			
		||||
            type: 'string',
 | 
			
		||||
            pattern: '^0x[0-9a-f]*$',
 | 
			
		||||
        },
 | 
			
		||||
        nonce: {
 | 
			
		||||
            type: 'number',
 | 
			
		||||
            minimum: 0,
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    required: [],
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    additionalProperties: false,
 | 
			
		||||
};
 | 
			
		||||
@@ -0,0 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/ecSignatureParameterSchema",
 | 
			
		||||
    "type": "string",
 | 
			
		||||
    "pattern": "^0[xX][0-9A-Fa-f]{64}$"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								packages/json-schemas/schemas/ec_signature_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								packages/json-schemas/schemas/ec_signature_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/ECSignature",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "v": {
 | 
			
		||||
            "type": "number",
 | 
			
		||||
            "minimum": 27,
 | 
			
		||||
            "maximum": 28
 | 
			
		||||
        },
 | 
			
		||||
        "r": { "$ref": "/ecSignatureParameterSchema" },
 | 
			
		||||
        "s": { "$ref": "/ecSignatureParameterSchema" }
 | 
			
		||||
    },
 | 
			
		||||
    "required": ["v", "r", "s"],
 | 
			
		||||
    "type": "object"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
export const ecSignatureParameterSchema = {
 | 
			
		||||
    id: '/ecSignatureParameterSchema',
 | 
			
		||||
    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: '/ecSignatureParameterSchema' },
 | 
			
		||||
        s: { $ref: '/ecSignatureParameterSchema' },
 | 
			
		||||
    },
 | 
			
		||||
    required: ['v', 'r', 's'],
 | 
			
		||||
    type: 'object',
 | 
			
		||||
};
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
export const eip712TypedDataSchema = {
 | 
			
		||||
    id: '/eip712TypedData',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    properties: {
 | 
			
		||||
        types: {
 | 
			
		||||
            type: 'object',
 | 
			
		||||
            properties: {
 | 
			
		||||
                EIP712Domain: { type: 'array' },
 | 
			
		||||
            },
 | 
			
		||||
            additionalProperties: {
 | 
			
		||||
                type: 'array',
 | 
			
		||||
                items: {
 | 
			
		||||
                    type: 'object',
 | 
			
		||||
                    properties: {
 | 
			
		||||
                        name: { type: 'string' },
 | 
			
		||||
                        type: { type: 'string' },
 | 
			
		||||
                    },
 | 
			
		||||
                    required: ['name', 'type'],
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
            required: ['EIP712Domain'],
 | 
			
		||||
        },
 | 
			
		||||
        primaryType: { type: 'string' },
 | 
			
		||||
        domain: { type: 'object' },
 | 
			
		||||
        message: { type: 'object' },
 | 
			
		||||
    },
 | 
			
		||||
    required: ['types', 'primaryType', 'domain', 'message'],
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										28
									
								
								packages/json-schemas/schemas/eip712_typed_data_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								packages/json-schemas/schemas/eip712_typed_data_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/eip712TypedDataSchema",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "types": {
 | 
			
		||||
            "type": "object",
 | 
			
		||||
            "properties": {
 | 
			
		||||
                "EIP712Domain": { "type": "array" }
 | 
			
		||||
            },
 | 
			
		||||
            "additionalProperties": {
 | 
			
		||||
                "type": "array",
 | 
			
		||||
                "items": {
 | 
			
		||||
                    "type": "object",
 | 
			
		||||
                    "properties": {
 | 
			
		||||
                        "name": { "type": "string" },
 | 
			
		||||
                        "type": { "type": "string" }
 | 
			
		||||
                    },
 | 
			
		||||
                    "required": ["name", "type"]
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "required": ["EIP712Domain"]
 | 
			
		||||
        },
 | 
			
		||||
        "primaryType": { "type": "string" },
 | 
			
		||||
        "domain": { "type": "object" },
 | 
			
		||||
        "message": { "type": "object" }
 | 
			
		||||
    },
 | 
			
		||||
    "required": ["types", "primaryType", "domain", "message"]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								packages/json-schemas/schemas/hex_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/json-schemas/schemas/hex_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/hexSchema",
 | 
			
		||||
    "type": "string",
 | 
			
		||||
    "pattern": "^0x(([0-9a-f][0-9a-f])+)?$"
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/indexFilterValuesSchema",
 | 
			
		||||
    "additionalProperties": {
 | 
			
		||||
        "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/addressSchema" }, { "$ref": "/orderHashSchema" }]
 | 
			
		||||
    },
 | 
			
		||||
    "type": "object"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
export const indexFilterValuesSchema = {
 | 
			
		||||
    id: '/indexFilterValuesSchema',
 | 
			
		||||
    additionalProperties: {
 | 
			
		||||
        oneOf: [{ $ref: '/numberSchema' }, { $ref: '/addressSchema' }, { $ref: '/orderHashSchema' }],
 | 
			
		||||
    },
 | 
			
		||||
    type: 'object',
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										5
									
								
								packages/json-schemas/schemas/js_number.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/json-schemas/schemas/js_number.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/jsNumber",
 | 
			
		||||
    "type": "number",
 | 
			
		||||
    "minimum": 0
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								packages/json-schemas/schemas/number_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/json-schemas/schemas/number_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/numberSchema",
 | 
			
		||||
    "type": "string",
 | 
			
		||||
    "pattern": "^\\d+(\\.\\d+)?$"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								packages/json-schemas/schemas/order_cancel_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								packages/json-schemas/schemas/order_cancel_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/orderCancellationRequestsSchema",
 | 
			
		||||
    "type": "array",
 | 
			
		||||
    "items": {
 | 
			
		||||
        "properties": {
 | 
			
		||||
            "order": { "$ref": "/orderSchema" },
 | 
			
		||||
            "takerTokenCancelAmount": { "$ref": "/numberSchema" }
 | 
			
		||||
        },
 | 
			
		||||
        "required": ["order", "takerTokenCancelAmount"],
 | 
			
		||||
        "type": "object"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
export const orderCancellationRequestsSchema = {
 | 
			
		||||
    id: '/orderCancellationRequestsSchema',
 | 
			
		||||
    type: 'array',
 | 
			
		||||
    items: {
 | 
			
		||||
        properties: {
 | 
			
		||||
            order: { $ref: '/orderSchema' },
 | 
			
		||||
            takerTokenCancelAmount: { $ref: '/numberSchema' },
 | 
			
		||||
        },
 | 
			
		||||
        required: ['order', 'takerTokenCancelAmount'],
 | 
			
		||||
        type: 'object',
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/orderFillOrKillRequestsSchema",
 | 
			
		||||
    "type": "array",
 | 
			
		||||
    "items": {
 | 
			
		||||
        "properties": {
 | 
			
		||||
            "signedOrder": { "$ref": "/signedOrderSchema" },
 | 
			
		||||
            "fillTakerAmount": { "$ref": "/numberSchema" }
 | 
			
		||||
        },
 | 
			
		||||
        "required": ["signedOrder", "fillTakerAmount"],
 | 
			
		||||
        "type": "object"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
export const orderFillOrKillRequestsSchema = {
 | 
			
		||||
    id: '/orderFillOrKillRequestsSchema',
 | 
			
		||||
    type: 'array',
 | 
			
		||||
    items: {
 | 
			
		||||
        properties: {
 | 
			
		||||
            signedOrder: { $ref: '/signedOrderSchema' },
 | 
			
		||||
            fillTakerAmount: { $ref: '/numberSchema' },
 | 
			
		||||
        },
 | 
			
		||||
        required: ['signedOrder', 'fillTakerAmount'],
 | 
			
		||||
        type: 'object',
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/orderFillRequestsSchema",
 | 
			
		||||
    "type": "array",
 | 
			
		||||
    "items": {
 | 
			
		||||
        "properties": {
 | 
			
		||||
            "signedOrder": { "$ref": "/signedOrderSchema" },
 | 
			
		||||
            "takerTokenFillAmount": { "$ref": "/numberSchema" }
 | 
			
		||||
        },
 | 
			
		||||
        "required": ["signedOrder", "takerTokenFillAmount"],
 | 
			
		||||
        "type": "object"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
export const orderFillRequestsSchema = {
 | 
			
		||||
    id: '/orderFillRequestsSchema',
 | 
			
		||||
    type: 'array',
 | 
			
		||||
    items: {
 | 
			
		||||
        properties: {
 | 
			
		||||
            signedOrder: { $ref: '/signedOrderSchema' },
 | 
			
		||||
            takerTokenFillAmount: { $ref: '/numberSchema' },
 | 
			
		||||
        },
 | 
			
		||||
        required: ['signedOrder', 'takerTokenFillAmount'],
 | 
			
		||||
        type: 'object',
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										5
									
								
								packages/json-schemas/schemas/order_hash_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/json-schemas/schemas/order_hash_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/orderHashSchema",
 | 
			
		||||
    "type": "string",
 | 
			
		||||
    "pattern": "^0x[0-9a-fA-F]{64}$"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
export const orderHashSchema = {
 | 
			
		||||
    id: '/orderHashSchema',
 | 
			
		||||
    type: 'string',
 | 
			
		||||
    pattern: '^0x[0-9a-fA-F]{64}$',
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										34
									
								
								packages/json-schemas/schemas/order_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								packages/json-schemas/schemas/order_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/orderSchema",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "makerAddress": { "$ref": "/addressSchema" },
 | 
			
		||||
        "takerAddress": { "$ref": "/addressSchema" },
 | 
			
		||||
        "makerFee": { "$ref": "/numberSchema" },
 | 
			
		||||
        "takerFee": { "$ref": "/numberSchema" },
 | 
			
		||||
        "senderAddress": { "$ref": "/addressSchema" },
 | 
			
		||||
        "makerAssetAmount": { "$ref": "/numberSchema" },
 | 
			
		||||
        "takerAssetAmount": { "$ref": "/numberSchema" },
 | 
			
		||||
        "makerAssetData": { "$ref": "/hexSchema" },
 | 
			
		||||
        "takerAssetData": { "$ref": "/hexSchema" },
 | 
			
		||||
        "salt": { "$ref": "/numberSchema" },
 | 
			
		||||
        "exchangeAddress": { "$ref": "/addressSchema" },
 | 
			
		||||
        "feeRecipientAddress": { "$ref": "/addressSchema" },
 | 
			
		||||
        "expirationTimeSeconds": { "$ref": "/numberSchema" }
 | 
			
		||||
    },
 | 
			
		||||
    "required": [
 | 
			
		||||
        "makerAddress",
 | 
			
		||||
        "takerAddress",
 | 
			
		||||
        "makerFee",
 | 
			
		||||
        "takerFee",
 | 
			
		||||
        "senderAddress",
 | 
			
		||||
        "makerAssetAmount",
 | 
			
		||||
        "takerAssetAmount",
 | 
			
		||||
        "makerAssetData",
 | 
			
		||||
        "takerAssetData",
 | 
			
		||||
        "salt",
 | 
			
		||||
        "exchangeAddress",
 | 
			
		||||
        "feeRecipientAddress",
 | 
			
		||||
        "expirationTimeSeconds"
 | 
			
		||||
    ],
 | 
			
		||||
    "type": "object"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
export const orderSchema = {
 | 
			
		||||
    id: '/orderSchema',
 | 
			
		||||
    properties: {
 | 
			
		||||
        makerAddress: { $ref: '/addressSchema' },
 | 
			
		||||
        takerAddress: { $ref: '/addressSchema' },
 | 
			
		||||
        makerFee: { $ref: '/numberSchema' },
 | 
			
		||||
        takerFee: { $ref: '/numberSchema' },
 | 
			
		||||
        senderAddress: { $ref: '/addressSchema' },
 | 
			
		||||
        makerAssetAmount: { $ref: '/numberSchema' },
 | 
			
		||||
        takerAssetAmount: { $ref: '/numberSchema' },
 | 
			
		||||
        makerAssetData: { $ref: '/hexSchema' },
 | 
			
		||||
        takerAssetData: { $ref: '/hexSchema' },
 | 
			
		||||
        salt: { $ref: '/numberSchema' },
 | 
			
		||||
        exchangeAddress: { $ref: '/addressSchema' },
 | 
			
		||||
        feeRecipientAddress: { $ref: '/addressSchema' },
 | 
			
		||||
        expirationTimeSeconds: { $ref: '/numberSchema' },
 | 
			
		||||
    },
 | 
			
		||||
    required: [
 | 
			
		||||
        'makerAddress',
 | 
			
		||||
        'takerAddress',
 | 
			
		||||
        'makerFee',
 | 
			
		||||
        'takerFee',
 | 
			
		||||
        'senderAddress',
 | 
			
		||||
        'makerAssetAmount',
 | 
			
		||||
        'takerAssetAmount',
 | 
			
		||||
        'makerAssetData',
 | 
			
		||||
        'takerAssetData',
 | 
			
		||||
        'salt',
 | 
			
		||||
        'exchangeAddress',
 | 
			
		||||
        'feeRecipientAddress',
 | 
			
		||||
        'expirationTimeSeconds',
 | 
			
		||||
    ],
 | 
			
		||||
    type: 'object',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const signedOrderSchema = {
 | 
			
		||||
    id: '/signedOrderSchema',
 | 
			
		||||
    allOf: [
 | 
			
		||||
        { $ref: '/orderSchema' },
 | 
			
		||||
        {
 | 
			
		||||
            properties: {
 | 
			
		||||
                signature: { $ref: '/hexSchema' },
 | 
			
		||||
            },
 | 
			
		||||
            required: ['signature'],
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										5
									
								
								packages/json-schemas/schemas/orders_schema.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/json-schemas/schemas/orders_schema.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/ordersSchema",
 | 
			
		||||
    "type": "array",
 | 
			
		||||
    "items": { "$ref": "/orderSchema" }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
export const ordersSchema = {
 | 
			
		||||
    id: '/ordersSchema',
 | 
			
		||||
    type: 'array',
 | 
			
		||||
    items: { $ref: '/orderSchema' },
 | 
			
		||||
};
 | 
			
		||||
@@ -0,0 +1,10 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/paginatedCollectionSchema",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "total": { "type": "number" },
 | 
			
		||||
        "perPage": { "type": "number" },
 | 
			
		||||
        "page": { "type": "number" }
 | 
			
		||||
    },
 | 
			
		||||
    "required": ["total", "perPage", "page"]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
export const paginatedCollectionSchema = {
 | 
			
		||||
    id: '/paginatedCollectionSchema',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    properties: {
 | 
			
		||||
        total: { type: 'number' },
 | 
			
		||||
        perPage: { type: 'number' },
 | 
			
		||||
        page: { type: 'number' },
 | 
			
		||||
    },
 | 
			
		||||
    required: ['total', 'perPage', 'page'],
 | 
			
		||||
};
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/relayerApiAssetDataPairsResponseSchema",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "allOf": [
 | 
			
		||||
        { "$ref": "/paginatedCollectionSchema" },
 | 
			
		||||
        {
 | 
			
		||||
            "properties": {
 | 
			
		||||
                "records": { "$ref": "/relayerApiAssetDataPairsSchema" }
 | 
			
		||||
            },
 | 
			
		||||
            "required": ["records"]
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/relayerApiAssetDataPairsSchema",
 | 
			
		||||
    "type": "array",
 | 
			
		||||
    "items": {
 | 
			
		||||
        "properties": {
 | 
			
		||||
            "assetDataA": { "$ref": "/relayerApiAssetDataTradeInfoSchema" },
 | 
			
		||||
            "assetDataB": { "$ref": "/relayerApiAssetDataTradeInfoSchema" }
 | 
			
		||||
        },
 | 
			
		||||
        "required": ["assetDataA", "assetDataB"],
 | 
			
		||||
        "type": "object"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/relayerApiAssetDataTradeInfoSchema",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "assetData": { "$ref": "/hexSchema" },
 | 
			
		||||
        "minAmount": { "$ref": "/numberSchema" },
 | 
			
		||||
        "maxAmount": { "$ref": "/numberSchema" },
 | 
			
		||||
        "precision": { "type": "number" }
 | 
			
		||||
    },
 | 
			
		||||
    "required": ["assetData"]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
export const relayerApiAssetDataPairsResponseSchema = {
 | 
			
		||||
    id: '/relayerApiAssetDataPairsResponseSchema',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    allOf: [
 | 
			
		||||
        { $ref: '/paginatedCollectionSchema' },
 | 
			
		||||
        {
 | 
			
		||||
            properties: {
 | 
			
		||||
                records: { $ref: '/relayerApiAssetDataPairsSchema' },
 | 
			
		||||
            },
 | 
			
		||||
            required: ['records'],
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const relayerApiAssetDataPairsSchema = {
 | 
			
		||||
    id: '/relayerApiAssetDataPairsSchema',
 | 
			
		||||
    type: 'array',
 | 
			
		||||
    items: {
 | 
			
		||||
        properties: {
 | 
			
		||||
            assetDataA: { $ref: '/relayerApiAssetDataTradeInfoSchema' },
 | 
			
		||||
            assetDataB: { $ref: '/relayerApiAssetDataTradeInfoSchema' },
 | 
			
		||||
        },
 | 
			
		||||
        required: ['assetDataA', 'assetDataB'],
 | 
			
		||||
        type: 'object',
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const relayerApiAssetDataTradeInfoSchema = {
 | 
			
		||||
    id: '/relayerApiAssetDataTradeInfoSchema',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    properties: {
 | 
			
		||||
        assetData: { $ref: '/hexSchema' },
 | 
			
		||||
        minAmount: { $ref: '/numberSchema' },
 | 
			
		||||
        maxAmount: { $ref: '/numberSchema' },
 | 
			
		||||
        precision: { type: 'number' },
 | 
			
		||||
    },
 | 
			
		||||
    required: ['assetData'],
 | 
			
		||||
};
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/relayerApiErrorResponseSchema",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "code": { "type": "integer", "minimum": 100, "maximum": 103 },
 | 
			
		||||
        "reason": { "type": "string" },
 | 
			
		||||
        "validationErrors": {
 | 
			
		||||
            "type": "array",
 | 
			
		||||
            "items": {
 | 
			
		||||
                "type": "object",
 | 
			
		||||
                "properties": {
 | 
			
		||||
                    "field": { "type": "string" },
 | 
			
		||||
                    "code": { "type": "integer", "minimum": 1000, "maximum": 1006 },
 | 
			
		||||
                    "reason": { "type": "string" }
 | 
			
		||||
                },
 | 
			
		||||
                "required": ["field", "code", "reason"]
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "required": ["code", "reason"]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
export const relayerApiErrorResponseSchema = {
 | 
			
		||||
    id: '/relayerApiErrorResponseSchema',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    properties: {
 | 
			
		||||
        code: { type: 'integer', minimum: 100, maximum: 103 },
 | 
			
		||||
        reason: { type: 'string' },
 | 
			
		||||
        validationErrors: {
 | 
			
		||||
            type: 'array',
 | 
			
		||||
            items: {
 | 
			
		||||
                type: 'object',
 | 
			
		||||
                properties: {
 | 
			
		||||
                    field: { type: 'string' },
 | 
			
		||||
                    code: { type: 'integer', minimum: 1000, maximum: 1006 },
 | 
			
		||||
                    reason: { type: 'string' },
 | 
			
		||||
                },
 | 
			
		||||
                required: ['field', 'code', 'reason'],
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    required: ['code', 'reason'],
 | 
			
		||||
};
 | 
			
		||||
@@ -0,0 +1,16 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/relayerApiFeeRecipientsResponseSchema",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "allOf": [
 | 
			
		||||
        { "$ref": "/paginatedCollectionSchema" },
 | 
			
		||||
        {
 | 
			
		||||
            "properties": {
 | 
			
		||||
                "records": {
 | 
			
		||||
                    "type": "array",
 | 
			
		||||
                    "items": { "$ref": "/addressSchema" }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "required": ["records"]
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
export const relayerApiFeeRecipientsResponseSchema = {
 | 
			
		||||
    id: '/relayerApiFeeRecipientsResponseSchema',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    allOf: [
 | 
			
		||||
        { $ref: '/paginatedCollectionSchema' },
 | 
			
		||||
        {
 | 
			
		||||
            properties: {
 | 
			
		||||
                records: {
 | 
			
		||||
                    type: 'array',
 | 
			
		||||
                    items: { $ref: '/addressSchema' },
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
            required: ['records'],
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
};
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/relayerApiOrderConfigPayloadSchema",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "makerAddress": { "$ref": "/addressSchema" },
 | 
			
		||||
        "takerAddress": { "$ref": "/addressSchema" },
 | 
			
		||||
        "makerAssetAmount": { "$ref": "/numberSchema" },
 | 
			
		||||
        "takerAssetAmount": { "$ref": "/numberSchema" },
 | 
			
		||||
        "makerAssetData": { "$ref": "/hexSchema" },
 | 
			
		||||
        "takerAssetData": { "$ref": "/hexSchema" },
 | 
			
		||||
        "exchangeAddress": { "$ref": "/addressSchema" },
 | 
			
		||||
        "expirationTimeSeconds": { "$ref": "/numberSchema" }
 | 
			
		||||
    },
 | 
			
		||||
    "required": [
 | 
			
		||||
        "makerAddress",
 | 
			
		||||
        "takerAddress",
 | 
			
		||||
        "makerAssetAmount",
 | 
			
		||||
        "takerAssetAmount",
 | 
			
		||||
        "makerAssetData",
 | 
			
		||||
        "takerAssetData",
 | 
			
		||||
        "exchangeAddress",
 | 
			
		||||
        "expirationTimeSeconds"
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
export const relayerApiOrderConfigPayloadSchema = {
 | 
			
		||||
    id: '/relayerApiOrderConfigPayloadSchema',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    properties: {
 | 
			
		||||
        makerAddress: { $ref: '/addressSchema' },
 | 
			
		||||
        takerAddress: { $ref: '/addressSchema' },
 | 
			
		||||
        makerAssetAmount: { $ref: '/numberSchema' },
 | 
			
		||||
        takerAssetAmount: { $ref: '/numberSchema' },
 | 
			
		||||
        makerAssetData: { $ref: '/hexSchema' },
 | 
			
		||||
        takerAssetData: { $ref: '/hexSchema' },
 | 
			
		||||
        exchangeAddress: { $ref: '/addressSchema' },
 | 
			
		||||
        expirationTimeSeconds: { $ref: '/numberSchema' },
 | 
			
		||||
    },
 | 
			
		||||
    required: [
 | 
			
		||||
        'makerAddress',
 | 
			
		||||
        'takerAddress',
 | 
			
		||||
        'makerAssetAmount',
 | 
			
		||||
        'takerAssetAmount',
 | 
			
		||||
        'makerAssetData',
 | 
			
		||||
        'takerAssetData',
 | 
			
		||||
        'exchangeAddress',
 | 
			
		||||
        'expirationTimeSeconds',
 | 
			
		||||
    ],
 | 
			
		||||
};
 | 
			
		||||
@@ -0,0 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/relayerApiOrderConfigResponseSchema",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "makerFee": { "$ref": "/numberSchema" },
 | 
			
		||||
        "takerFee": { "$ref": "/numberSchema" },
 | 
			
		||||
        "feeRecipientAddress": { "$ref": "/addressSchema" },
 | 
			
		||||
        "senderAddress": { "$ref": "/addressSchema" }
 | 
			
		||||
    },
 | 
			
		||||
    "required": ["makerFee", "takerFee", "feeRecipientAddress", "senderAddress"]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
export const relayerApiOrderConfigResponseSchema = {
 | 
			
		||||
    id: '/relayerApiOrderConfigResponseSchema',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    properties: {
 | 
			
		||||
        makerFee: { $ref: '/numberSchema' },
 | 
			
		||||
        takerFee: { $ref: '/numberSchema' },
 | 
			
		||||
        feeRecipientAddress: { $ref: '/addressSchema' },
 | 
			
		||||
        senderAddress: { $ref: '/addressSchema' },
 | 
			
		||||
    },
 | 
			
		||||
    required: ['makerFee', 'takerFee', 'feeRecipientAddress', 'senderAddress'],
 | 
			
		||||
};
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
    "id": "/relayerApiOrderSchema",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "properties": {
 | 
			
		||||
        "order": { "$ref": "/orderSchema" },
 | 
			
		||||
        "metaData": { "type": "object" }
 | 
			
		||||
    },
 | 
			
		||||
    "required": ["order", "metaData"]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
export const relayerApiOrderSchema = {
 | 
			
		||||
    id: '/relayerApiOrderSchema',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    properties: {
 | 
			
		||||
        order: { $ref: '/orderSchema' },
 | 
			
		||||
        metaData: { type: 'object' },
 | 
			
		||||
    },
 | 
			
		||||
    required: ['order', 'metaData'],
 | 
			
		||||
};
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user