From 0499541e114e6dd36565428f4f914e0dbdece2b8 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 24 Apr 2018 16:36:35 +0200 Subject: Move order utils to @0xproject/order-utils --- packages/order-utils/.npmignore | 6 + packages/order-utils/CHANGELOG.json | 1 + packages/order-utils/README.md | 77 ++++++++++ packages/order-utils/coverage/.gitkeep | 0 packages/order-utils/package.json | 76 ++++++++++ packages/order-utils/src/assert.ts | 35 +++++ packages/order-utils/src/constants.ts | 3 + packages/order-utils/src/globals.d.ts | 6 + packages/order-utils/src/index.ts | 7 + .../src/monorepo_scripts/postpublish.ts | 8 ++ .../order-utils/src/monorepo_scripts/stage_docs.ts | 8 ++ packages/order-utils/src/order_factory.ts | 49 +++++++ packages/order-utils/src/order_hash.ts | 89 ++++++++++++ packages/order-utils/src/salt.ts | 18 +++ packages/order-utils/src/signature_utils.ts | 119 ++++++++++++++++ packages/order-utils/src/types.ts | 3 + packages/order-utils/test/assert_test.ts | 35 +++++ packages/order-utils/test/order_hash_test.ts | 46 ++++++ packages/order-utils/test/signature_utils_test.ts | 157 +++++++++++++++++++++ packages/order-utils/test/utils/chai_setup.ts | 13 ++ packages/order-utils/test/utils/web3_wrapper.ts | 9 ++ packages/order-utils/tsconfig.json | 7 + packages/order-utils/tslint.json | 3 + 23 files changed, 775 insertions(+) create mode 100644 packages/order-utils/.npmignore create mode 100644 packages/order-utils/CHANGELOG.json create mode 100644 packages/order-utils/README.md create mode 100644 packages/order-utils/coverage/.gitkeep create mode 100644 packages/order-utils/package.json create mode 100644 packages/order-utils/src/assert.ts create mode 100644 packages/order-utils/src/constants.ts create mode 100644 packages/order-utils/src/globals.d.ts create mode 100644 packages/order-utils/src/index.ts create mode 100644 packages/order-utils/src/monorepo_scripts/postpublish.ts create mode 100644 packages/order-utils/src/monorepo_scripts/stage_docs.ts create mode 100644 packages/order-utils/src/order_factory.ts create mode 100644 packages/order-utils/src/order_hash.ts create mode 100644 packages/order-utils/src/salt.ts create mode 100644 packages/order-utils/src/signature_utils.ts create mode 100644 packages/order-utils/src/types.ts create mode 100644 packages/order-utils/test/assert_test.ts create mode 100644 packages/order-utils/test/order_hash_test.ts create mode 100644 packages/order-utils/test/signature_utils_test.ts create mode 100644 packages/order-utils/test/utils/chai_setup.ts create mode 100644 packages/order-utils/test/utils/web3_wrapper.ts create mode 100644 packages/order-utils/tsconfig.json create mode 100644 packages/order-utils/tslint.json (limited to 'packages/order-utils') diff --git a/packages/order-utils/.npmignore b/packages/order-utils/.npmignore new file mode 100644 index 000000000..24e65ad5b --- /dev/null +++ b/packages/order-utils/.npmignore @@ -0,0 +1,6 @@ +.* +yarn-error.log +/scripts/ +/src/ +tsconfig.json +/lib/monorepo_scripts/ diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/packages/order-utils/CHANGELOG.json @@ -0,0 +1 @@ +[] diff --git a/packages/order-utils/README.md b/packages/order-utils/README.md new file mode 100644 index 000000000..4b571509a --- /dev/null +++ b/packages/order-utils/README.md @@ -0,0 +1,77 @@ +## @0xproject/order-utils + +0x order-related utilities for those developing on top of 0x protocol. + +### Read the [Documentation](https://0xproject.com/docs/order-utils). + +## Installation + +```bash +yarn add @0xproject/order-utils +``` + +If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`: + +```json +"compilerOptions": { + "typeRoots": ["node_modules/@0xproject/typescript-typings/types", "node_modules/@types"], +} +``` + +## Contributing + +We welcome improvements and fixes from the wider community! To report bugs within this package, please create an issue in this repository. + +Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started. + +### Install dependencies + +If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them: + +```bash +yarn config set workspaces-experimental true +``` + +Then install dependencies + +```bash +yarn install +``` + +### Build + +If this is your **first** time building this package, you must first build **all** packages within the monorepo. This is because packages that depend on other packages located inside this monorepo are symlinked when run from **within** the monorepo. This allows you to make changes across multiple packages without first publishing dependent packages to NPM. To build all packages, run the following from the monorepo root directory: + +```bash +yarn lerna:rebuild +``` + +Or continuously rebuild on change: + +```bash +yarn dev +``` + +You can also build this specific package by running the following from within its directory: + +```bash +yarn build +``` + +or continuously rebuild on change: + +```bash +yarn build:watch +``` + +### Clean + +```bash +yarn clean +``` + +### Lint + +```bash +yarn lint +``` diff --git a/packages/order-utils/coverage/.gitkeep b/packages/order-utils/coverage/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json new file mode 100644 index 000000000..cb21139a2 --- /dev/null +++ b/packages/order-utils/package.json @@ -0,0 +1,76 @@ +{ + "name": "@0xproject/order-utils", + "version": "0.0.1", + "description": "0x order utils", + "main": "lib/src/index.js", + "types": "lib/src/index.d.ts", + "scripts": { + "build:watch": "tsc -w", + "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", + "test": "run-s clean build run_mocha", + "test:circleci": "yarn test:coverage", + "run_mocha": "mocha lib/test/**/*_test.js --bail --exit", + "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", + "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", + "clean": "shx rm -rf lib scripts", + "lint": "tslint --project .", + "manual:postpublish": "yarn build; node ./scripts/postpublish.js", + "docs:stage": "yarn build && node ./scripts/stage_docs.js", + "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES", + "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json" + }, + "config": { + "postpublish": { + "docPublishConfigs": { + "extraFileIncludes": [ + "../types/src/index.ts" + ], + "s3BucketPath": "s3://doc-jsons/order-utils/", + "s3StagingBucketPath": "s3://staging-doc-jsons/order-utils/" + } + } + }, + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/0xProject/0x-monorepo.git" + }, + "bugs": { + "url": "https://github.com/0xProject/0x-monorepo/issues" + }, + "homepage": "https://github.com/0xProject/0x-monorepo/packages/order-utils/README.md", + "devDependencies": { + "@0xproject/monorepo-scripts": "^0.1.18", + "@0xproject/dev-utils": "^0.3.6", + "@0xproject/tslint-config": "^0.4.16", + "@types/lodash": "4.14.104", + "chai": "^4.0.1", + "chai-as-promised": "^7.1.0", + "chai-bignumber": "^2.0.1", + "dirty-chai": "^2.0.1", + "sinon": "^4.0.0", + "mocha": "^4.0.1", + "copyfiles": "^1.2.0", + "npm-run-all": "^4.1.2", + "typedoc": "0xProject/typedoc", + "shx": "^0.2.2", + "tslint": "5.8.0", + "typescript": "2.7.1" + }, + "dependencies": { + "@0xproject/assert": "^0.2.7", + "@0xproject/types": "^0.6.1", + "@0xproject/json-schemas": "^0.7.21", + "@0xproject/typescript-typings": "^0.2.0", + "@0xproject/web3-wrapper": "^0.6.1", + "@0xproject/utils": "^0.5.2", + "@types/node": "^8.0.53", + "bn.js": "^4.11.8", + "lodash": "^4.17.4", + "ethereumjs-abi": "^0.6.4", + "ethereumjs-util": "^5.1.1" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/order-utils/src/assert.ts b/packages/order-utils/src/assert.ts new file mode 100644 index 000000000..92641b845 --- /dev/null +++ b/packages/order-utils/src/assert.ts @@ -0,0 +1,35 @@ +import { assert as sharedAssert } from '@0xproject/assert'; +// We need those two unused imports because they're actually used by sharedAssert which gets injected here +// tslint:disable-next-line:no-unused-variable +import { Schema } from '@0xproject/json-schemas'; +// tslint:disable-next-line:no-unused-variable +import { ECSignature } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as _ from 'lodash'; + +import { isValidSignature } from './signature_utils'; + +export const assert = { + ...sharedAssert, + isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string) { + const isValid = isValidSignature(orderHash, ecSignature, signerAddress); + this.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`); + }, + async isSenderAddressAsync( + variableName: string, + senderAddressHex: string, + web3Wrapper: Web3Wrapper, + ): Promise { + sharedAssert.isETHAddressHex(variableName, senderAddressHex); + const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex); + sharedAssert.assert( + isSenderAddressAvailable, + `Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`, + ); + }, + async isUserAddressAvailableAsync(web3Wrapper: Web3Wrapper): Promise { + const availableAddresses = await web3Wrapper.getAvailableAddressesAsync(); + this.assert(!_.isEmpty(availableAddresses), 'No addresses were available on the provided web3 provider'); + }, +}; diff --git a/packages/order-utils/src/constants.ts b/packages/order-utils/src/constants.ts new file mode 100644 index 000000000..ec2fe744a --- /dev/null +++ b/packages/order-utils/src/constants.ts @@ -0,0 +1,3 @@ +export const constants = { + NULL_ADDRESS: '0x0000000000000000000000000000000000000000', +}; diff --git a/packages/order-utils/src/globals.d.ts b/packages/order-utils/src/globals.d.ts new file mode 100644 index 000000000..94e63a32d --- /dev/null +++ b/packages/order-utils/src/globals.d.ts @@ -0,0 +1,6 @@ +declare module '*.json' { + const json: any; + /* tslint:disable */ + export default json; + /* tslint:enable */ +} diff --git a/packages/order-utils/src/index.ts b/packages/order-utils/src/index.ts new file mode 100644 index 000000000..4addd60d6 --- /dev/null +++ b/packages/order-utils/src/index.ts @@ -0,0 +1,7 @@ +export { getOrderHashHex, isValidOrderHash } from './order_hash'; +export { isValidSignature, signOrderHashAsync } from './signature_utils'; +export { orderFactory } from './order_factory'; +export { generatePseudoRandomSalt } from './salt'; +export { assert } from './assert'; +export { constants } from './constants'; +export { OrderError } from './types'; diff --git a/packages/order-utils/src/monorepo_scripts/postpublish.ts b/packages/order-utils/src/monorepo_scripts/postpublish.ts new file mode 100644 index 000000000..dcb99d0f7 --- /dev/null +++ b/packages/order-utils/src/monorepo_scripts/postpublish.ts @@ -0,0 +1,8 @@ +import { postpublishUtils } from '@0xproject/monorepo-scripts'; + +import * as packageJSON from '../package.json'; +import * as tsConfigJSON from '../tsconfig.json'; + +const cwd = `${__dirname}/..`; +// tslint:disable-next-line:no-floating-promises +postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd); diff --git a/packages/order-utils/src/monorepo_scripts/stage_docs.ts b/packages/order-utils/src/monorepo_scripts/stage_docs.ts new file mode 100644 index 000000000..e732ac8eb --- /dev/null +++ b/packages/order-utils/src/monorepo_scripts/stage_docs.ts @@ -0,0 +1,8 @@ +import { postpublishUtils } from '@0xproject/monorepo-scripts'; + +import * as packageJSON from '../package.json'; +import * as tsConfigJSON from '../tsconfig.json'; + +const cwd = `${__dirname}/..`; +// tslint:disable-next-line:no-floating-promises +postpublishUtils.publishDocsToStagingAsync(packageJSON, tsConfigJSON, cwd); diff --git a/packages/order-utils/src/order_factory.ts b/packages/order-utils/src/order_factory.ts new file mode 100644 index 000000000..2759aac81 --- /dev/null +++ b/packages/order-utils/src/order_factory.ts @@ -0,0 +1,49 @@ +import { Provider, SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; + +import { getOrderHashHex } from './order_hash'; +import { generatePseudoRandomSalt } from './salt'; +import { signOrderHashAsync } from './signature_utils'; + +const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false; + +export const orderFactory = { + async createSignedOrderAsync( + provider: Provider, + maker: string, + taker: string, + makerFee: BigNumber, + takerFee: BigNumber, + makerTokenAmount: BigNumber, + makerTokenAddress: string, + takerTokenAmount: BigNumber, + takerTokenAddress: string, + exchangeContractAddress: string, + feeRecipient: string, + expirationUnixTimestampSecIfExists?: BigNumber, + ): Promise { + const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite + const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists) + ? defaultExpirationUnixTimestampSec + : expirationUnixTimestampSecIfExists; + const order = { + maker, + taker, + makerFee, + takerFee, + makerTokenAmount, + takerTokenAmount, + makerTokenAddress, + takerTokenAddress, + salt: generatePseudoRandomSalt(), + exchangeContractAddress, + feeRecipient, + expirationUnixTimestampSec, + }; + const orderHash = getOrderHashHex(order); + const ecSignature = await signOrderHashAsync(provider, orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX); + const signedOrder: SignedOrder = _.assign(order, { ecSignature }); + return signedOrder; + }, +}; diff --git a/packages/order-utils/src/order_hash.ts b/packages/order-utils/src/order_hash.ts new file mode 100644 index 000000000..8da11c596 --- /dev/null +++ b/packages/order-utils/src/order_hash.ts @@ -0,0 +1,89 @@ +import { schemas, SchemaValidator } from '@0xproject/json-schemas'; +import { Order, SignedOrder, SolidityTypes } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import BN = require('bn.js'); +import * as ethABI from 'ethereumjs-abi'; +import * as ethUtil from 'ethereumjs-util'; +import * as _ from 'lodash'; + +import { assert } from './assert'; + +const INVALID_TAKER_FORMAT = 'instance.taker is not of a type(s) string'; + +/** + * Converts BigNumber instance to BN + * The only reason we convert to BN is to remain compatible with `ethABI.soliditySHA3` that + * expects values of Solidity type `uint` to be passed as type `BN`. + * We do not use BN anywhere else in the codebase. + */ +function bigNumberToBN(value: BigNumber) { + return new BN(value.toString(), 10); +} + +/** + * Computes the orderHash for a supplied order. + * @param order An object that conforms to the Order or SignedOrder interface definitions. + * @return The resulting orderHash from hashing the supplied order. + */ +export function getOrderHashHex(order: Order | SignedOrder): string { + try { + assert.doesConformToSchema('order', order, schemas.orderSchema); + } catch (error) { + if (_.includes(error.message, INVALID_TAKER_FORMAT)) { + const errMsg = + 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS'; + throw new Error(errMsg); + } + throw error; + } + const orderParts = [ + { value: order.exchangeContractAddress, type: SolidityTypes.Address }, + { value: order.maker, type: SolidityTypes.Address }, + { value: order.taker, type: SolidityTypes.Address }, + { value: order.makerTokenAddress, type: SolidityTypes.Address }, + { value: order.takerTokenAddress, type: SolidityTypes.Address }, + { value: order.feeRecipient, type: SolidityTypes.Address }, + { + value: bigNumberToBN(order.makerTokenAmount), + type: SolidityTypes.Uint256, + }, + { + value: bigNumberToBN(order.takerTokenAmount), + type: SolidityTypes.Uint256, + }, + { + value: bigNumberToBN(order.makerFee), + type: SolidityTypes.Uint256, + }, + { + value: bigNumberToBN(order.takerFee), + type: SolidityTypes.Uint256, + }, + { + value: bigNumberToBN(order.expirationUnixTimestampSec), + type: SolidityTypes.Uint256, + }, + { value: bigNumberToBN(order.salt), type: SolidityTypes.Uint256 }, + ]; + const types = _.map(orderParts, o => o.type); + const values = _.map(orderParts, o => o.value); + const hashBuff = ethABI.soliditySHA3(types, values); + const hashHex = ethUtil.bufferToHex(hashBuff); + return hashHex; +} + +/** + * Checks if the supplied hex encoded order hash is valid. + * Note: Valid means it has the expected format, not that an order with the orderHash exists. + * Use this method when processing orderHashes submitted as user input. + * @param orderHash Hex encoded orderHash. + * @return Whether the supplied orderHash has the expected format. + */ +export function isValidOrderHash(orderHash: string): boolean { + // Since this method can be called to check if any arbitrary string conforms to an orderHash's + // format, we only assert that we were indeed passed a string. + assert.isString('orderHash', orderHash); + const schemaValidator = new SchemaValidator(); + const isValid = schemaValidator.validate(orderHash, schemas.orderHashSchema).valid; + return isValid; +} diff --git a/packages/order-utils/src/salt.ts b/packages/order-utils/src/salt.ts new file mode 100644 index 000000000..90a4197c0 --- /dev/null +++ b/packages/order-utils/src/salt.ts @@ -0,0 +1,18 @@ +import { BigNumber } from '@0xproject/utils'; + +const MAX_DIGITS_IN_UNSIGNED_256_INT = 78; + +/** + * Generates a pseudo-random 256-bit salt. + * The salt can be included in a 0x order, ensuring that the order generates a unique orderHash + * and will not collide with other outstanding orders that are identical in all other parameters. + * @return A pseudo-random 256-bit number that can be used as a salt. + */ +export function generatePseudoRandomSalt(): BigNumber { + // BigNumber.random returns a pseudo-random number between 0 & 1 with a passed in number of decimal places. + // Source: https://mikemcl.github.io/bignumber.js/#random + const randomNumber = BigNumber.random(MAX_DIGITS_IN_UNSIGNED_256_INT); + const factor = new BigNumber(10).pow(MAX_DIGITS_IN_UNSIGNED_256_INT - 1); + const salt = randomNumber.times(factor).round(); + return salt; +} diff --git a/packages/order-utils/src/signature_utils.ts b/packages/order-utils/src/signature_utils.ts new file mode 100644 index 000000000..b511573a8 --- /dev/null +++ b/packages/order-utils/src/signature_utils.ts @@ -0,0 +1,119 @@ +import { schemas } from '@0xproject/json-schemas'; +import { ECSignature, Provider } from '@0xproject/types'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as ethUtil from 'ethereumjs-util'; +import * as _ from 'lodash'; + +import { assert } from './assert'; +import { OrderError } from './types'; + +/** + * Verifies that the elliptic curve signature `signature` was generated + * by signing `data` with the private key corresponding to the `signerAddress` address. + * @param data The hex encoded data signed by the supplied signature. + * @param signature An object containing the elliptic curve signature parameters. + * @param signerAddress The hex encoded address that signed the data, producing the supplied signature. + * @return Whether the signature is valid for the supplied signerAddress and data. + */ +export function isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean { + assert.isHexString('data', data); + assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema); + assert.isETHAddressHex('signerAddress', signerAddress); + const normalizedSignerAddress = signerAddress.toLowerCase(); + + const dataBuff = ethUtil.toBuffer(data); + const msgHashBuff = ethUtil.hashPersonalMessage(dataBuff); + try { + const pubKey = ethUtil.ecrecover( + msgHashBuff, + signature.v, + ethUtil.toBuffer(signature.r), + ethUtil.toBuffer(signature.s), + ); + const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey)); + return retrievedAddress === signerAddress; + } catch (err) { + return false; + } +} +/** + * Signs an orderHash and returns it's elliptic curve signature. + * This method currently supports TestRPC, Geth and Parity above and below V1.6.6 + * @param orderHash Hex encoded orderHash to sign. + * @param signerAddress The hex encoded Ethereum address you wish to sign it with. This address + * must be available via the Provider supplied to 0x.js. + * @param shouldAddPersonalMessagePrefix Some signers add the personal message prefix `\x19Ethereum Signed Message` + * themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client + * (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix + * before sending the request. + * @return An object containing the Elliptic curve signature parameters generated by signing the orderHash. + */ +export async function signOrderHashAsync( + provider: Provider, + orderHash: string, + signerAddress: string, + shouldAddPersonalMessagePrefix: boolean, +): Promise { + assert.isHexString('orderHash', orderHash); + const web3Wrapper = new Web3Wrapper(provider); + await assert.isSenderAddressAsync('signerAddress', signerAddress, web3Wrapper); + const normalizedSignerAddress = signerAddress.toLowerCase(); + + let msgHashHex = orderHash; + if (shouldAddPersonalMessagePrefix) { + const orderHashBuff = ethUtil.toBuffer(orderHash); + const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff); + msgHashHex = ethUtil.bufferToHex(msgHashBuff); + } + + const signature = await web3Wrapper.signMessageAsync(normalizedSignerAddress, msgHashHex); + + // HACK: There is no consensus on whether the signatureHex string should be formatted as + // v + r + s OR r + s + v, and different clients (even different versions of the same client) + // return the signature params in different orders. In order to support all client implementations, + // we parse the signature in both ways, and evaluate if either one is a valid signature. + const validVParamValues = [27, 28]; + const ecSignatureVRS = parseSignatureHexAsVRS(signature); + if (_.includes(validVParamValues, ecSignatureVRS.v)) { + const isValidVRSSignature = isValidSignature(orderHash, ecSignatureVRS, normalizedSignerAddress); + if (isValidVRSSignature) { + return ecSignatureVRS; + } + } + + const ecSignatureRSV = parseSignatureHexAsRSV(signature); + if (_.includes(validVParamValues, ecSignatureRSV.v)) { + const isValidRSVSignature = isValidSignature(orderHash, ecSignatureRSV, normalizedSignerAddress); + if (isValidRSVSignature) { + return ecSignatureRSV; + } + } + + throw new Error(OrderError.InvalidSignature); +} + +function parseSignatureHexAsVRS(signatureHex: string): ECSignature { + const signatureBuffer = ethUtil.toBuffer(signatureHex); + let v = signatureBuffer[0]; + if (v < 27) { + v += 27; + } + const r = signatureBuffer.slice(1, 33); + const s = signatureBuffer.slice(33, 65); + const ecSignature: ECSignature = { + v, + r: ethUtil.bufferToHex(r), + s: ethUtil.bufferToHex(s), + }; + return ecSignature; +} + +function parseSignatureHexAsRSV(signatureHex: string): ECSignature { + const { v, r, s } = ethUtil.fromRpcSig(signatureHex); + const ecSignature: ECSignature = { + v, + r: ethUtil.bufferToHex(r), + s: ethUtil.bufferToHex(s), + }; + return ecSignature; +} diff --git a/packages/order-utils/src/types.ts b/packages/order-utils/src/types.ts new file mode 100644 index 000000000..f79d52359 --- /dev/null +++ b/packages/order-utils/src/types.ts @@ -0,0 +1,3 @@ +export enum OrderError { + InvalidSignature = 'INVALID_SIGNATURE', +} diff --git a/packages/order-utils/test/assert_test.ts b/packages/order-utils/test/assert_test.ts new file mode 100644 index 000000000..dfd19bf86 --- /dev/null +++ b/packages/order-utils/test/assert_test.ts @@ -0,0 +1,35 @@ +import { web3Factory } from '@0xproject/dev-utils'; +import * as chai from 'chai'; +import 'mocha'; + +import { assert } from '../src/assert'; + +import { chaiSetup } from './utils/chai_setup'; +import { web3Wrapper } from './utils/web3_wrapper'; + +chaiSetup.configure(); +const expect = chai.expect; + +describe('Assertion library', () => { + describe('#isSenderAddressHexAsync', () => { + it('throws when address is invalid', async () => { + const address = '0xdeadbeef'; + const varName = 'address'; + return expect(assert.isSenderAddressAsync(varName, address, web3Wrapper)).to.be.rejectedWith( + `Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`, + ); + }); + it('throws when address is unavailable', async () => { + const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42'; + const varName = 'address'; + return expect(assert.isSenderAddressAsync(varName, validUnrelatedAddress, web3Wrapper)).to.be.rejectedWith( + `Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`, + ); + }); + it("doesn't throw if address is available", async () => { + const availableAddress = (await web3Wrapper.getAvailableAddressesAsync())[0]; + const varName = 'address'; + return expect(assert.isSenderAddressAsync(varName, availableAddress, web3Wrapper)).to.become(undefined); + }); + }); +}); diff --git a/packages/order-utils/test/order_hash_test.ts b/packages/order-utils/test/order_hash_test.ts new file mode 100644 index 000000000..b6dda1a43 --- /dev/null +++ b/packages/order-utils/test/order_hash_test.ts @@ -0,0 +1,46 @@ +import { web3Factory } from '@0xproject/dev-utils'; +import { BigNumber } from '@0xproject/utils'; +import * as chai from 'chai'; +import 'mocha'; + +import { constants, getOrderHashHex } from '../src'; + +import { chaiSetup } from './utils/chai_setup'; +import { web3Wrapper } from './utils/web3_wrapper'; + +chaiSetup.configure(); +const expect = chai.expect; + +describe('Order hashing', () => { + describe('#getOrderHashHex', () => { + const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83'; + const fakeExchangeContractAddress = '0xb69e673309512a9d726f87304c6984054f87a93b'; + const order = { + maker: constants.NULL_ADDRESS, + taker: constants.NULL_ADDRESS, + feeRecipient: constants.NULL_ADDRESS, + makerTokenAddress: constants.NULL_ADDRESS, + takerTokenAddress: constants.NULL_ADDRESS, + exchangeContractAddress: fakeExchangeContractAddress, + salt: new BigNumber(0), + makerFee: new BigNumber(0), + takerFee: new BigNumber(0), + makerTokenAmount: new BigNumber(0), + takerTokenAmount: new BigNumber(0), + expirationUnixTimestampSec: new BigNumber(0), + }; + it('calculates the order hash', async () => { + const orderHash = getOrderHashHex(order); + expect(orderHash).to.be.equal(expectedOrderHash); + }); + it('throws a readable error message if taker format is invalid', async () => { + const orderWithInvalidtakerFormat = { + ...order, + taker: (null as any) as string, + }; + const expectedErrorMessage = + 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS'; + expect(() => getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage); + }); + }); +}); diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts new file mode 100644 index 000000000..7af67ae2e --- /dev/null +++ b/packages/order-utils/test/signature_utils_test.ts @@ -0,0 +1,157 @@ +import { web3Factory } from '@0xproject/dev-utils'; +import { JSONRPCErrorCallback, JSONRPCRequestPayload } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import * as chai from 'chai'; +import * as _ from 'lodash'; +import 'mocha'; +import * as Sinon from 'sinon'; + +import { generatePseudoRandomSalt, isValidOrderHash, isValidSignature, signOrderHashAsync } from '../src'; + +import { chaiSetup } from './utils/chai_setup'; +import { provider, web3Wrapper } from './utils/web3_wrapper'; + +chaiSetup.configure(); +const expect = chai.expect; + +const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false; + +describe('Signature utils', () => { + describe('#isValidSignature', () => { + // The Exchange smart contract `isValidSignature` method only validates orderHashes and assumes + // the length of the data is exactly 32 bytes. Thus for these tests, we use data of this size. + const dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0'; + const signature = { + v: 27, + r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33', + s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', + }; + const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631'; + it("should return false if the data doesn't pertain to the signature & address", async () => { + expect(isValidSignature('0x0', signature, address)).to.be.false(); + }); + it("should return false if the address doesn't pertain to the signature & data", async () => { + const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42'; + expect(isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false(); + }); + it("should return false if the signature doesn't pertain to the dataHex & address", async () => { + const wrongSignature = _.assign({}, signature, { v: 28 }); + expect(isValidSignature(dataHex, wrongSignature, address)).to.be.false(); + }); + it('should return true if the signature does pertain to the dataHex & address', async () => { + const isValidSignatureLocal = isValidSignature(dataHex, signature, address); + expect(isValidSignatureLocal).to.be.true(); + }); + }); + describe('#generateSalt', () => { + it('generates different salts', () => { + const equal = generatePseudoRandomSalt().eq(generatePseudoRandomSalt()); + expect(equal).to.be.false(); + }); + it('generates salt in range [0..2^256)', () => { + const salt = generatePseudoRandomSalt(); + expect(salt.greaterThanOrEqualTo(0)).to.be.true(); + const twoPow256 = new BigNumber(2).pow(256); + expect(salt.lessThan(twoPow256)).to.be.true(); + }); + }); + describe('#isValidOrderHash', () => { + it('returns false if the value is not a hex string', () => { + const isValid = isValidOrderHash('not a hex'); + expect(isValid).to.be.false(); + }); + it('returns false if the length is wrong', () => { + const isValid = isValidOrderHash('0xdeadbeef'); + expect(isValid).to.be.false(); + }); + it('returns true if order hash is correct', () => { + const isValid = isValidOrderHash('0x' + Array(65).join('0')); + expect(isValid).to.be.true(); + }); + }); + describe('#signOrderHashAsync', () => { + let stubs: Sinon.SinonStub[] = []; + let makerAddress: string; + before(async () => { + const availableAddreses = await web3Wrapper.getAvailableAddressesAsync(); + makerAddress = availableAddreses[0]; + }); + afterEach(() => { + // clean up any stubs after the test has completed + _.each(stubs, s => s.restore()); + stubs = []; + }); + it('Should return the correct ECSignature', async () => { + const orderHash = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0'; + const expectedECSignature = { + v: 27, + r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33', + s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', + }; + const ecSignature = await signOrderHashAsync( + provider, + orderHash, + makerAddress, + SHOULD_ADD_PERSONAL_MESSAGE_PREFIX, + ); + expect(ecSignature).to.deep.equal(expectedECSignature); + }); + it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => { + const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004'; + const signature = + '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b'; + const expectedECSignature = { + v: 27, + r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3', + s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02', + }; + stubs = [Sinon.stub('isValidSignature').returns(true)]; + + const fakeProvider = { + sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback) { + if (payload.method === 'eth_sign') { + callback(null, { id: 42, jsonrpc: '2.0', result: signature }); + } else { + callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] }); + } + }, + }; + + const ecSignature = await signOrderHashAsync( + fakeProvider, + orderHash, + makerAddress, + SHOULD_ADD_PERSONAL_MESSAGE_PREFIX, + ); + expect(ecSignature).to.deep.equal(expectedECSignature); + }); + it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => { + const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7'; + const signature = + '0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960'; + const expectedECSignature = { + v: 27, + r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0', + s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960', + }; + stubs = [Sinon.stub('isValidSignature').returns(true)]; + const fakeProvider = { + sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback) { + if (payload.method === 'eth_sign') { + callback(null, { id: 42, jsonrpc: '2.0', result: signature }); + } else { + callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] }); + } + }, + }; + + const ecSignature = await signOrderHashAsync( + fakeProvider, + orderHash, + makerAddress, + SHOULD_ADD_PERSONAL_MESSAGE_PREFIX, + ); + expect(ecSignature).to.deep.equal(expectedECSignature); + }); + }); +}); diff --git a/packages/order-utils/test/utils/chai_setup.ts b/packages/order-utils/test/utils/chai_setup.ts new file mode 100644 index 000000000..078edd309 --- /dev/null +++ b/packages/order-utils/test/utils/chai_setup.ts @@ -0,0 +1,13 @@ +import * as chai from 'chai'; +import chaiAsPromised = require('chai-as-promised'); +import ChaiBigNumber = require('chai-bignumber'); +import * as dirtyChai from 'dirty-chai'; + +export const chaiSetup = { + configure() { + chai.config.includeStack = true; + chai.use(ChaiBigNumber()); + chai.use(dirtyChai); + chai.use(chaiAsPromised); + }, +}; diff --git a/packages/order-utils/test/utils/web3_wrapper.ts b/packages/order-utils/test/utils/web3_wrapper.ts new file mode 100644 index 000000000..b0ccfa546 --- /dev/null +++ b/packages/order-utils/test/utils/web3_wrapper.ts @@ -0,0 +1,9 @@ +import { devConstants, web3Factory } from '@0xproject/dev-utils'; +import { Provider } from '@0xproject/types'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; + +const web3 = web3Factory.create({ shouldUseInProcessGanache: true }); +const provider: Provider = web3.currentProvider; +const web3Wrapper = new Web3Wrapper(web3.currentProvider); + +export { provider, web3Wrapper }; diff --git a/packages/order-utils/tsconfig.json b/packages/order-utils/tsconfig.json new file mode 100644 index 000000000..8b4cd47a2 --- /dev/null +++ b/packages/order-utils/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "lib" + }, + "include": ["src/**/*", "test/**/*"] +} diff --git a/packages/order-utils/tslint.json b/packages/order-utils/tslint.json new file mode 100644 index 000000000..ffaefe83a --- /dev/null +++ b/packages/order-utils/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": ["@0xproject/tslint-config"] +} -- cgit v1.2.3 From adaff92c9243e7e13737f92cf4b6ade77ebd6e43 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 2 May 2018 15:25:30 +0300 Subject: Create wrapper functions so that docs render properly --- packages/order-utils/.npmignore | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/order-utils') diff --git a/packages/order-utils/.npmignore b/packages/order-utils/.npmignore index 24e65ad5b..89302c908 100644 --- a/packages/order-utils/.npmignore +++ b/packages/order-utils/.npmignore @@ -1,6 +1,7 @@ .* yarn-error.log /scripts/ +/generated_docs/ /src/ tsconfig.json /lib/monorepo_scripts/ -- cgit v1.2.3 From a6046af0240d9257a9e9dd80dc4dc5f533df8799 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 2 May 2018 18:38:38 +0300 Subject: Stop exporting assertions from order-utils --- packages/order-utils/src/assert.ts | 8 -------- packages/order-utils/src/index.ts | 1 - 2 files changed, 9 deletions(-) (limited to 'packages/order-utils') diff --git a/packages/order-utils/src/assert.ts b/packages/order-utils/src/assert.ts index 92641b845..5ac402e7e 100644 --- a/packages/order-utils/src/assert.ts +++ b/packages/order-utils/src/assert.ts @@ -12,10 +12,6 @@ import { isValidSignature } from './signature_utils'; export const assert = { ...sharedAssert, - isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string) { - const isValid = isValidSignature(orderHash, ecSignature, signerAddress); - this.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`); - }, async isSenderAddressAsync( variableName: string, senderAddressHex: string, @@ -28,8 +24,4 @@ export const assert = { `Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`, ); }, - async isUserAddressAvailableAsync(web3Wrapper: Web3Wrapper): Promise { - const availableAddresses = await web3Wrapper.getAvailableAddressesAsync(); - this.assert(!_.isEmpty(availableAddresses), 'No addresses were available on the provided web3 provider'); - }, }; diff --git a/packages/order-utils/src/index.ts b/packages/order-utils/src/index.ts index 4addd60d6..2b565f713 100644 --- a/packages/order-utils/src/index.ts +++ b/packages/order-utils/src/index.ts @@ -2,6 +2,5 @@ export { getOrderHashHex, isValidOrderHash } from './order_hash'; export { isValidSignature, signOrderHashAsync } from './signature_utils'; export { orderFactory } from './order_factory'; export { generatePseudoRandomSalt } from './salt'; -export { assert } from './assert'; export { constants } from './constants'; export { OrderError } from './types'; -- cgit v1.2.3 From 3585326d7eb82ae730752d1956876b22f7638fa6 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 2 May 2018 19:30:32 +0300 Subject: Fix signature utils tests --- packages/order-utils/test/signature_utils_test.ts | 37 ++++++++++++++--------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'packages/order-utils') diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts index 7af67ae2e..ede681619 100644 --- a/packages/order-utils/test/signature_utils_test.ts +++ b/packages/order-utils/test/signature_utils_test.ts @@ -7,6 +7,7 @@ import 'mocha'; import * as Sinon from 'sinon'; import { generatePseudoRandomSalt, isValidOrderHash, isValidSignature, signOrderHashAsync } from '../src'; +import * as signatureUtils from '../src/signature_utils'; import { chaiSetup } from './utils/chai_setup'; import { provider, web3Wrapper } from './utils/web3_wrapper'; @@ -98,19 +99,22 @@ describe('Signature utils', () => { }); it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => { const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004'; - const signature = - '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b'; const expectedECSignature = { v: 27, - r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3', - s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02', + r: '0x117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d87287113', + s: '0x7feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b', }; - stubs = [Sinon.stub('isValidSignature').returns(true)]; const fakeProvider = { - sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback) { + async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback) { if (payload.method === 'eth_sign') { - callback(null, { id: 42, jsonrpc: '2.0', result: signature }); + const [address, message] = payload.params; + const signature = await web3Wrapper.signMessageAsync(address, message); + callback(null, { + id: 42, + jsonrpc: '2.0', + result: `0x${signature.substr(130)}${signature.substr(2, 128)}`, + }); } else { callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] }); } @@ -126,19 +130,22 @@ describe('Signature utils', () => { expect(ecSignature).to.deep.equal(expectedECSignature); }); it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => { - const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7'; - const signature = - '0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960'; + const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004'; const expectedECSignature = { v: 27, - r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0', - s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960', + r: '0x117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d87287113', + s: '0x7feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b', }; - stubs = [Sinon.stub('isValidSignature').returns(true)]; const fakeProvider = { - sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback) { + async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback) { if (payload.method === 'eth_sign') { - callback(null, { id: 42, jsonrpc: '2.0', result: signature }); + const [address, message] = payload.params; + const signature = await web3Wrapper.signMessageAsync(address, message); + callback(null, { + id: 42, + jsonrpc: '2.0', + result: signature, + }); } else { callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] }); } -- cgit v1.2.3 From 3fc99dbad5f7f727f7474473c261a7b512045e63 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 4 May 2018 12:16:11 +0200 Subject: Updated CHANGELOGS --- packages/order-utils/CHANGELOG.json | 12 +++++++++++- packages/order-utils/CHANGELOG.md | 10 ++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 packages/order-utils/CHANGELOG.md (limited to 'packages/order-utils') diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index fe51488c7..de494e387 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -1 +1,11 @@ -[] +[ + { + "timestamp": 1525428773, + "version": "0.0.2", + "changes": [ + { + "note": "Dependencies updated" + } + ] + } +] diff --git a/packages/order-utils/CHANGELOG.md b/packages/order-utils/CHANGELOG.md new file mode 100644 index 000000000..dedf40986 --- /dev/null +++ b/packages/order-utils/CHANGELOG.md @@ -0,0 +1,10 @@ + + +CHANGELOG + +## v0.0.2 - _May 4, 2018_ + + * Dependencies updated -- cgit v1.2.3 From 8dd91248639d167d198df949d7749a93d6af5bf3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 4 May 2018 12:16:17 +0200 Subject: Publish - 0x.js@0.37.0 - @0xproject/abi-gen@0.2.12 - @0xproject/assert@0.2.8 - @0xproject/base-contract@0.3.0 - @0xproject/connect@0.6.11 - contracts@2.1.26 - @0xproject/deployer@0.4.2 - @0xproject/dev-utils@0.4.0 - @0xproject/json-schemas@0.7.22 - @0xproject/metacoin@0.0.5 - @0xproject/migrations@0.0.4 - @0xproject/monorepo-scripts@0.1.19 - @0xproject/order-utils@0.0.2 - @0xproject/react-docs-example@0.0.9 - @0xproject/react-docs@0.0.9 - @0xproject/react-shared@0.1.4 - @0xproject/sol-cov@0.0.9 - @0xproject/sol-resolver@0.0.3 - @0xproject/sra-report@0.0.12 - @0xproject/subproviders@0.10.0 - @0xproject/testnet-faucets@1.0.27 - @0xproject/tslint-config@0.4.17 - @0xproject/types@0.6.2 - @0xproject/typescript-typings@0.3.0 - @0xproject/utils@0.6.0 - @0xproject/web3-wrapper@0.6.2 - @0xproject/website@0.0.29 --- packages/order-utils/package.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'packages/order-utils') diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json index cb21139a2..d787db435 100644 --- a/packages/order-utils/package.json +++ b/packages/order-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/order-utils", - "version": "0.0.1", + "version": "0.0.2", "description": "0x order utils", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", @@ -40,35 +40,35 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/order-utils/README.md", "devDependencies": { - "@0xproject/monorepo-scripts": "^0.1.18", - "@0xproject/dev-utils": "^0.3.6", - "@0xproject/tslint-config": "^0.4.16", + "@0xproject/dev-utils": "^0.4.0", + "@0xproject/monorepo-scripts": "^0.1.19", + "@0xproject/tslint-config": "^0.4.17", "@types/lodash": "4.14.104", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.1", + "copyfiles": "^1.2.0", "dirty-chai": "^2.0.1", - "sinon": "^4.0.0", "mocha": "^4.0.1", - "copyfiles": "^1.2.0", "npm-run-all": "^4.1.2", - "typedoc": "0xProject/typedoc", "shx": "^0.2.2", + "sinon": "^4.0.0", "tslint": "5.8.0", + "typedoc": "0xProject/typedoc", "typescript": "2.7.1" }, "dependencies": { - "@0xproject/assert": "^0.2.7", - "@0xproject/types": "^0.6.1", - "@0xproject/json-schemas": "^0.7.21", - "@0xproject/typescript-typings": "^0.2.0", - "@0xproject/web3-wrapper": "^0.6.1", - "@0xproject/utils": "^0.5.2", + "@0xproject/assert": "^0.2.8", + "@0xproject/json-schemas": "^0.7.22", + "@0xproject/types": "^0.6.2", + "@0xproject/typescript-typings": "^0.3.0", + "@0xproject/utils": "^0.6.0", + "@0xproject/web3-wrapper": "^0.6.2", "@types/node": "^8.0.53", "bn.js": "^4.11.8", - "lodash": "^4.17.4", "ethereumjs-abi": "^0.6.4", - "ethereumjs-util": "^5.1.1" + "ethereumjs-util": "^5.1.1", + "lodash": "^4.17.4" }, "publishConfig": { "access": "public" -- cgit v1.2.3 From 91fdd6fc292327c5f021d2718d7e9aa0dd1b39ca Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 4 May 2018 19:07:02 +0200 Subject: Make a negligible change to order-utils to publish a new version --- packages/order-utils/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/order-utils') diff --git a/packages/order-utils/src/index.ts b/packages/order-utils/src/index.ts index 2b565f713..b85432c84 100644 --- a/packages/order-utils/src/index.ts +++ b/packages/order-utils/src/index.ts @@ -1,6 +1,6 @@ export { getOrderHashHex, isValidOrderHash } from './order_hash'; export { isValidSignature, signOrderHashAsync } from './signature_utils'; export { orderFactory } from './order_factory'; -export { generatePseudoRandomSalt } from './salt'; export { constants } from './constants'; +export { generatePseudoRandomSalt } from './salt'; export { OrderError } from './types'; -- cgit v1.2.3 From ae68c3abe4a6e76d9f82e8225dab21356d539435 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 4 May 2018 20:44:12 +0200 Subject: Updated CHANGELOGS --- packages/order-utils/CHANGELOG.json | 9 +++++++++ packages/order-utils/CHANGELOG.md | 4 ++++ 2 files changed, 13 insertions(+) (limited to 'packages/order-utils') diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index de494e387..ecd3b96ae 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1525453812, + "version": "0.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1525428773, "version": "0.0.2", diff --git a/packages/order-utils/CHANGELOG.md b/packages/order-utils/CHANGELOG.md index dedf40986..3e858e0a3 100644 --- a/packages/order-utils/CHANGELOG.md +++ b/packages/order-utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v0.0.3 - _May 4, 2018_ + + * Dependencies updated + ## v0.0.2 - _May 4, 2018_ * Dependencies updated -- cgit v1.2.3 From b4cb21b55ec6dc3089cd6a152fe1b414284a7264 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 4 May 2018 20:44:18 +0200 Subject: Publish - 0x.js@0.37.1 - contracts@2.1.27 - @0xproject/order-utils@0.0.3 - @0xproject/sra-report@0.0.13 - @0xproject/testnet-faucets@1.0.28 - @0xproject/website@0.0.30 --- packages/order-utils/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/order-utils') diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json index d787db435..cb6f1ed41 100644 --- a/packages/order-utils/package.json +++ b/packages/order-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/order-utils", - "version": "0.0.2", + "version": "0.0.3", "description": "0x order utils", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", -- cgit v1.2.3 From bf87b1a6af5bf6041c7051272568ff3d67ba3f9c Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Sat, 5 May 2018 01:55:04 +0200 Subject: Updated CHANGELOGS --- packages/order-utils/CHANGELOG.json | 9 +++++++++ packages/order-utils/CHANGELOG.md | 4 ++++ 2 files changed, 13 insertions(+) (limited to 'packages/order-utils') diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index ecd3b96ae..44f919bc2 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1525477860, + "version": "0.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1525453812, "version": "0.0.3", diff --git a/packages/order-utils/CHANGELOG.md b/packages/order-utils/CHANGELOG.md index 3e858e0a3..d0bb706aa 100644 --- a/packages/order-utils/CHANGELOG.md +++ b/packages/order-utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v0.0.4 - _May 5, 2018_ + + * Dependencies updated + ## v0.0.3 - _May 4, 2018_ * Dependencies updated -- cgit v1.2.3 From 69a6166b6a1d39afc24b8dd950ec5d8539a03420 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Sat, 5 May 2018 01:55:12 +0200 Subject: Publish - 0x.js@0.37.2 - @0xproject/abi-gen@0.2.13 - @0xproject/assert@0.2.9 - @0xproject/base-contract@0.3.1 - @0xproject/connect@0.6.12 - contracts@2.1.28 - @0xproject/deployer@0.4.3 - @0xproject/dev-utils@0.4.1 - @0xproject/json-schemas@0.7.23 - @0xproject/metacoin@0.0.6 - @0xproject/migrations@0.0.5 - @0xproject/order-utils@0.0.4 - @0xproject/react-docs-example@0.0.11 - @0xproject/react-docs@0.0.11 - @0xproject/react-shared@0.1.6 - @0xproject/sol-cov@0.0.10 - @0xproject/sol-resolver@0.0.4 - @0xproject/sra-report@0.0.14 - @0xproject/subproviders@0.10.1 - @0xproject/testnet-faucets@1.0.29 - @0xproject/types@0.6.3 - @0xproject/typescript-typings@0.3.1 - @0xproject/utils@0.6.1 - @0xproject/web3-wrapper@0.6.3 - @0xproject/website@0.0.32 --- packages/order-utils/package.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'packages/order-utils') diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json index cb6f1ed41..cdb5b63b0 100644 --- a/packages/order-utils/package.json +++ b/packages/order-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/order-utils", - "version": "0.0.3", + "version": "0.0.4", "description": "0x order utils", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", @@ -40,7 +40,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/order-utils/README.md", "devDependencies": { - "@0xproject/dev-utils": "^0.4.0", + "@0xproject/dev-utils": "^0.4.1", "@0xproject/monorepo-scripts": "^0.1.19", "@0xproject/tslint-config": "^0.4.17", "@types/lodash": "4.14.104", @@ -58,12 +58,12 @@ "typescript": "2.7.1" }, "dependencies": { - "@0xproject/assert": "^0.2.8", - "@0xproject/json-schemas": "^0.7.22", - "@0xproject/types": "^0.6.2", - "@0xproject/typescript-typings": "^0.3.0", - "@0xproject/utils": "^0.6.0", - "@0xproject/web3-wrapper": "^0.6.2", + "@0xproject/assert": "^0.2.9", + "@0xproject/json-schemas": "^0.7.23", + "@0xproject/types": "^0.6.3", + "@0xproject/typescript-typings": "^0.3.1", + "@0xproject/utils": "^0.6.1", + "@0xproject/web3-wrapper": "^0.6.3", "@types/node": "^8.0.53", "bn.js": "^4.11.8", "ethereumjs-abi": "^0.6.4", -- cgit v1.2.3