aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-utils/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/order-utils/src')
-rw-r--r--packages/order-utils/src/constants.ts10
-rw-r--r--packages/order-utils/src/eip712_utils.ts55
-rw-r--r--packages/order-utils/src/index.ts12
-rw-r--r--packages/order-utils/src/order_hash.ts17
-rw-r--r--packages/order-utils/src/transaction_hash.ts46
5 files changed, 112 insertions, 28 deletions
diff --git a/packages/order-utils/src/constants.ts b/packages/order-utils/src/constants.ts
index a9a687719..3c93575b3 100644
--- a/packages/order-utils/src/constants.ts
+++ b/packages/order-utils/src/constants.ts
@@ -68,9 +68,9 @@ export const constants = {
SELECTOR_CHAR_LENGTH_WITH_PREFIX: 10,
INFINITE_TIMESTAMP_SEC: new BigNumber(2524604400), // Close to infinite
ZERO_AMOUNT: new BigNumber(0),
- EIP712_DOMAIN_NAME: '0x Protocol',
- EIP712_DOMAIN_VERSION: '2',
- EIP712_DOMAIN_SCHEMA: {
+ EXCHANGE_DOMAIN_NAME: '0x Protocol',
+ EXCHANGE_DOMAIN_VERSION: '2',
+ DEFAULT_DOMAIN_SCHEMA: {
name: 'EIP712Domain',
parameters: [
{ name: 'name', type: 'string' },
@@ -78,7 +78,7 @@ export const constants = {
{ name: 'verifyingContract', type: 'address' },
],
},
- EIP712_ORDER_SCHEMA: {
+ EXCHANGE_ORDER_SCHEMA: {
name: 'Order',
parameters: [
{ name: 'makerAddress', type: 'address' },
@@ -95,7 +95,7 @@ export const constants = {
{ name: 'takerAssetData', type: 'bytes' },
],
},
- EIP712_ZEROEX_TRANSACTION_SCHEMA: {
+ EXCHANGE_ZEROEX_TRANSACTION_SCHEMA: {
name: 'ZeroExTransaction',
parameters: [
{ name: 'salt', type: 'uint256' },
diff --git a/packages/order-utils/src/eip712_utils.ts b/packages/order-utils/src/eip712_utils.ts
index 385fda989..313653c63 100644
--- a/packages/order-utils/src/eip712_utils.ts
+++ b/packages/order-utils/src/eip712_utils.ts
@@ -1,36 +1,49 @@
import { assert } from '@0x/assert';
import { schemas } from '@0x/json-schemas';
-import { EIP712Object, EIP712TypedData, EIP712Types, Order, ZeroExTransaction } from '@0x/types';
+import {
+ EIP712DomainWithDefaultSchema,
+ EIP712Object,
+ EIP712TypedData,
+ EIP712Types,
+ Order,
+ ZeroExTransaction,
+} from '@0x/types';
import * as _ from 'lodash';
import { constants } from './constants';
+export const DEFAULT_DOMAIN_SCHEMA = constants.DEFAULT_DOMAIN_SCHEMA;
+export const EXCHANGE_DOMAIN_NAME = constants.EXCHANGE_DOMAIN_NAME;
+export const EXCHANGE_DOMAIN_VERSION = constants.EXCHANGE_DOMAIN_VERSION;
+export const EXCHANGE_ORDER_SCHEMA = constants.EXCHANGE_ORDER_SCHEMA;
+export const EXCHANGE_ZEROEX_TRANSACTION_SCHEMA = constants.EXCHANGE_ZEROEX_TRANSACTION_SCHEMA;
+
export const eip712Utils = {
/**
* Creates a EIP712TypedData object specific to the 0x protocol for use with signTypedData.
* @param primaryType The primary type found in message
* @param types The additional types for the data in message
* @param message The contents of the message
- * @param exchangeAddress The address of the exchange contract
+ * @param domain Domain containing a name (optional), version (optional), and verifying contract address
* @return A typed data object
*/
createTypedData: (
primaryType: string,
types: EIP712Types,
message: EIP712Object,
- exchangeAddress: string,
+ domain: EIP712DomainWithDefaultSchema,
): EIP712TypedData => {
- assert.isETHAddressHex('exchangeAddress', exchangeAddress);
+ assert.isETHAddressHex('verifyingContractAddress', domain.verifyingContractAddress);
assert.isString('primaryType', primaryType);
const typedData = {
types: {
- EIP712Domain: constants.EIP712_DOMAIN_SCHEMA.parameters,
+ EIP712Domain: DEFAULT_DOMAIN_SCHEMA.parameters,
...types,
},
domain: {
- name: constants.EIP712_DOMAIN_NAME,
- version: constants.EIP712_DOMAIN_VERSION,
- verifyingContract: exchangeAddress,
+ name: _.isUndefined(domain.name) ? EXCHANGE_DOMAIN_NAME : domain.name,
+ version: _.isUndefined(domain.version) ? EXCHANGE_DOMAIN_VERSION : domain.version,
+ verifyingContract: domain.verifyingContractAddress,
},
message,
primaryType,
@@ -48,11 +61,14 @@ export const eip712Utils = {
const normalizedOrder = _.mapValues(order, value => {
return !_.isString(value) ? value.toString() : value;
});
+ const domain = {
+ verifyingContractAddress: order.exchangeAddress,
+ };
const typedData = eip712Utils.createTypedData(
- constants.EIP712_ORDER_SCHEMA.name,
- { Order: constants.EIP712_ORDER_SCHEMA.parameters },
+ EXCHANGE_ORDER_SCHEMA.name,
+ { Order: EXCHANGE_ORDER_SCHEMA.parameters },
normalizedOrder,
- order.exchangeAddress,
+ domain,
);
return typedData;
},
@@ -60,23 +76,22 @@ export const eip712Utils = {
* Creates an ExecuteTransaction EIP712TypedData object for use with signTypedData and
* 0x Exchange executeTransaction.
* @param ZeroExTransaction the 0x transaction
- * @param exchangeAddress The address of the exchange contract
* @return A typed data object
*/
- createZeroExTransactionTypedData: (
- zeroExTransaction: ZeroExTransaction,
- exchangeAddress: string,
- ): EIP712TypedData => {
- assert.isETHAddressHex('exchangeAddress', exchangeAddress);
+ createZeroExTransactionTypedData: (zeroExTransaction: ZeroExTransaction): EIP712TypedData => {
+ assert.isETHAddressHex('verifyingContractAddress', zeroExTransaction.verifyingContractAddress);
assert.doesConformToSchema('zeroExTransaction', zeroExTransaction, schemas.zeroExTransactionSchema);
const normalizedTransaction = _.mapValues(zeroExTransaction, value => {
return !_.isString(value) ? value.toString() : value;
});
+ const domain = {
+ verifyingContractAddress: zeroExTransaction.verifyingContractAddress,
+ };
const typedData = eip712Utils.createTypedData(
- constants.EIP712_ZEROEX_TRANSACTION_SCHEMA.name,
- { ZeroExTransaction: constants.EIP712_ZEROEX_TRANSACTION_SCHEMA.parameters },
+ EXCHANGE_ZEROEX_TRANSACTION_SCHEMA.name,
+ { ZeroExTransaction: EXCHANGE_ZEROEX_TRANSACTION_SCHEMA.parameters },
normalizedTransaction,
- exchangeAddress,
+ domain,
);
return typedData;
},
diff --git a/packages/order-utils/src/index.ts b/packages/order-utils/src/index.ts
index 2150a02e4..436677efc 100644
--- a/packages/order-utils/src/index.ts
+++ b/packages/order-utils/src/index.ts
@@ -3,6 +3,7 @@ export { signatureUtils } from './signature_utils';
export { generatePseudoRandomSalt } from './salt';
export { assetDataUtils } from './asset_data_utils';
export { marketUtils } from './market_utils';
+export { transactionHashUtils } from './transaction_hash';
export { rateUtils } from './rate_utils';
export { sortingUtils } from './sorting_utils';
export { orderParsingUtils } from './parsing_utils';
@@ -18,7 +19,14 @@ export { ExchangeTransferSimulator } from './exchange_transfer_simulator';
export { BalanceAndProxyAllowanceLazyStore } from './store/balance_and_proxy_allowance_lazy_store';
export { OrderFilledCancelledLazyStore } from './store/order_filled_cancelled_lazy_store';
-export { eip712Utils } from './eip712_utils';
+export {
+ eip712Utils,
+ DEFAULT_DOMAIN_SCHEMA,
+ EXCHANGE_DOMAIN_NAME,
+ EXCHANGE_DOMAIN_VERSION,
+ EXCHANGE_ORDER_SCHEMA,
+ EXCHANGE_ZEROEX_TRANSACTION_SCHEMA,
+} from './eip712_utils';
export {
Provider,
@@ -50,7 +58,9 @@ export {
EIP712Types,
EIP712Object,
EIP712ObjectValue,
+ EIP712DomainWithDefaultSchema,
ZeroExTransaction,
+ SignedZeroExTransaction,
} from '@0x/types';
export {
OrderError,
diff --git a/packages/order-utils/src/order_hash.ts b/packages/order-utils/src/order_hash.ts
index c8e9be71e..ce7e6d85f 100644
--- a/packages/order-utils/src/order_hash.ts
+++ b/packages/order-utils/src/order_hash.ts
@@ -4,6 +4,7 @@ import { signTypedDataUtils } from '@0x/utils';
import * as _ from 'lodash';
import { assert } from './assert';
+import { constants } from './constants';
import { eip712Utils } from './eip712_utils';
const INVALID_TAKER_FORMAT = 'instance.takerAddress is not of a type(s) string';
@@ -34,8 +35,9 @@ export const orderHashUtils = {
assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]);
} 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';
+ const errMsg = `Order taker must be of type string. If you want anyone to be able to fill an order - pass ${
+ constants.NULL_ADDRESS
+ }`;
throw new Error(errMsg);
}
throw error;
@@ -51,6 +53,17 @@ export const orderHashUtils = {
* @return A Buffer containing the resulting orderHash from hashing the supplied order
*/
getOrderHashBuffer(order: SignedOrder | Order): Buffer {
+ try {
+ assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]);
+ } 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 ${
+ constants.NULL_ADDRESS
+ }`;
+ throw new Error(errMsg);
+ }
+ throw error;
+ }
const typedData = eip712Utils.createOrderTypedData(order);
const orderHashBuff = signTypedDataUtils.generateTypedDataHash(typedData);
return orderHashBuff;
diff --git a/packages/order-utils/src/transaction_hash.ts b/packages/order-utils/src/transaction_hash.ts
new file mode 100644
index 000000000..2b2345af7
--- /dev/null
+++ b/packages/order-utils/src/transaction_hash.ts
@@ -0,0 +1,46 @@
+import { schemas, SchemaValidator } from '@0x/json-schemas';
+import { SignedZeroExTransaction, ZeroExTransaction } from '@0x/types';
+import { signTypedDataUtils } from '@0x/utils';
+import * as _ from 'lodash';
+
+import { assert } from './assert';
+import { eip712Utils } from './eip712_utils';
+
+export const transactionHashUtils = {
+ /**
+ * Checks if the supplied hex encoded 0x transaction hash is valid.
+ * Note: Valid means it has the expected format, not that a transaction with the transactionHash exists.
+ * Use this method when processing transactionHashes submitted as user input.
+ * @param transactionHash Hex encoded transactionHash.
+ * @return Whether the supplied transactionHash has the expected format.
+ */
+ isValidTransactionHash(transactionHash: string): boolean {
+ // Since this method can be called to check if any arbitrary string conforms to an transactionHash's
+ // format, we only assert that we were indeed passed a string.
+ assert.isString('transactionHash', transactionHash);
+ const schemaValidator = new SchemaValidator();
+ const isValid = schemaValidator.validate(transactionHash, schemas.orderHashSchema).valid;
+ return isValid;
+ },
+ /**
+ * Computes the transactionHash for a supplied 0x transaction.
+ * @param transaction An object that conforms to the ZeroExTransaction or SignedZeroExTransaction interface definitions.
+ * @return Hex encoded string transactionHash from hashing the supplied order.
+ */
+ getTransactionHashHex(transaction: ZeroExTransaction | SignedZeroExTransaction): string {
+ assert.doesConformToSchema('transaction', transaction, schemas.zeroExTransactionSchema, [schemas.hexSchema]);
+ const transactionHashBuff = transactionHashUtils.getTransactionHashBuffer(transaction);
+ const transactionHashHex = `0x${transactionHashBuff.toString('hex')}`;
+ return transactionHashHex;
+ },
+ /**
+ * Computes the transactionHash for a supplied 0x transaction.
+ * @param transaction An object that conforms to the ZeroExTransaction or SignedZeroExTransaction interface definitions.
+ * @return A Buffer containing the resulting transactionHash from hashing the supplied 0x transaction.
+ */
+ getTransactionHashBuffer(transaction: ZeroExTransaction | SignedZeroExTransaction): Buffer {
+ const typedData = eip712Utils.createZeroExTransactionTypedData(transaction);
+ const transactionHashBuff = signTypedDataUtils.generateTypedDataHash(typedData);
+ return transactionHashBuff;
+ },
+};