Allow custom domains in eip712Utils
This commit is contained in:
@@ -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' },
|
||||
|
@@ -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 verifyingContractAddress The address of the verifying 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,
|
||||
verifyingContractAddress: string,
|
||||
domain: EIP712DomainWithDefaultSchema,
|
||||
): EIP712TypedData => {
|
||||
assert.isETHAddressHex('verifyingContractAddress', verifyingContractAddress);
|
||||
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: verifyingContractAddress,
|
||||
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;
|
||||
},
|
||||
@@ -68,11 +84,14 @@ export const eip712Utils = {
|
||||
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,
|
||||
zeroExTransaction.verifyingContractAddress,
|
||||
domain,
|
||||
);
|
||||
return typedData;
|
||||
},
|
||||
|
@@ -19,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,
|
||||
@@ -51,6 +58,7 @@ export {
|
||||
EIP712Types,
|
||||
EIP712Object,
|
||||
EIP712ObjectValue,
|
||||
EIP712DomainWithDefaultSchema,
|
||||
ZeroExTransaction,
|
||||
SignedZeroExTransaction,
|
||||
} from '@0x/types';
|
||||
|
@@ -61,7 +61,6 @@ export const orderHashUtils = {
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
const typedData = eip712Utils.createOrderTypedData(order);
|
||||
const orderHashBuff = signTypedDataUtils.generateTypedDataHash(typedData);
|
||||
return orderHashBuff;
|
||||
|
@@ -3,7 +3,12 @@ import * as chai from 'chai';
|
||||
import 'mocha';
|
||||
|
||||
import { constants } from '../src/constants';
|
||||
import { eip712Utils } from '../src/eip712_utils';
|
||||
import {
|
||||
eip712Utils,
|
||||
EXCHANGE_DOMAIN_NAME,
|
||||
EXCHANGE_DOMAIN_VERSION,
|
||||
EXCHANGE_ZEROEX_TRANSACTION_SCHEMA,
|
||||
} from '../src/eip712_utils';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
|
||||
@@ -12,22 +17,42 @@ const expect = chai.expect;
|
||||
|
||||
describe('EIP712 Utils', () => {
|
||||
describe('createTypedData', () => {
|
||||
it('adds in the EIP712DomainSeparator', () => {
|
||||
it('adds in the EIP712DomainSeparator with default values', () => {
|
||||
const primaryType = 'Test';
|
||||
const typedData = eip712Utils.createTypedData(
|
||||
primaryType,
|
||||
{ Test: [{ name: 'testValue', type: 'uint256' }] },
|
||||
{ testValue: '1' },
|
||||
constants.NULL_ADDRESS,
|
||||
{ verifyingContractAddress: constants.NULL_ADDRESS },
|
||||
);
|
||||
expect(typedData.domain).to.not.be.undefined();
|
||||
expect(typedData.types.EIP712Domain).to.not.be.undefined();
|
||||
const domainObject = typedData.domain;
|
||||
expect(domainObject.name).to.eq(constants.EIP712_DOMAIN_NAME);
|
||||
expect(domainObject.name).to.eq(EXCHANGE_DOMAIN_NAME);
|
||||
expect(domainObject.version).to.eq(EXCHANGE_DOMAIN_VERSION);
|
||||
expect(domainObject.verifyingContract).to.eq(constants.NULL_ADDRESS);
|
||||
expect(typedData.primaryType).to.eq(primaryType);
|
||||
});
|
||||
it('adds in the EIP712DomainSeparator without default values', () => {
|
||||
const primaryType = 'Test';
|
||||
const domainName = 'testDomain';
|
||||
const domainVersion = 'testVersion';
|
||||
const typedData = eip712Utils.createTypedData(
|
||||
primaryType,
|
||||
{ Test: [{ name: 'testValue', type: 'uint256' }] },
|
||||
{ testValue: '1' },
|
||||
{ name: domainName, version: domainVersion, verifyingContractAddress: constants.NULL_ADDRESS },
|
||||
);
|
||||
expect(typedData.domain).to.not.be.undefined();
|
||||
expect(typedData.types.EIP712Domain).to.not.be.undefined();
|
||||
const domainObject = typedData.domain;
|
||||
expect(domainObject.name).to.eq(domainName);
|
||||
expect(domainObject.version).to.eq(domainVersion);
|
||||
expect(domainObject.verifyingContract).to.eq(constants.NULL_ADDRESS);
|
||||
expect(typedData.primaryType).to.eq(primaryType);
|
||||
});
|
||||
});
|
||||
describe('createTypedData', () => {
|
||||
describe('createZeroExTransactionTypedData', () => {
|
||||
it('adds in the EIP712DomainSeparator', () => {
|
||||
const typedData = eip712Utils.createZeroExTransactionTypedData({
|
||||
salt: new BigNumber('0'),
|
||||
@@ -35,8 +60,12 @@ describe('EIP712 Utils', () => {
|
||||
signerAddress: constants.NULL_ADDRESS,
|
||||
verifyingContractAddress: constants.NULL_ADDRESS,
|
||||
});
|
||||
expect(typedData.primaryType).to.eq(constants.EIP712_ZEROEX_TRANSACTION_SCHEMA.name);
|
||||
expect(typedData.primaryType).to.eq(EXCHANGE_ZEROEX_TRANSACTION_SCHEMA.name);
|
||||
expect(typedData.types.EIP712Domain).to.not.be.undefined();
|
||||
const domainObject = typedData.domain;
|
||||
expect(domainObject.name).to.eq(EXCHANGE_DOMAIN_NAME);
|
||||
expect(domainObject.version).to.eq(EXCHANGE_DOMAIN_VERSION);
|
||||
expect(domainObject.verifyingContract).to.eq(constants.NULL_ADDRESS);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -690,3 +690,9 @@ export interface DutchAuctionDetails {
|
||||
currentAmount: BigNumber;
|
||||
currentTimeSeconds: BigNumber;
|
||||
}
|
||||
|
||||
export interface EIP712DomainWithDefaultSchema {
|
||||
name?: string;
|
||||
version?: string;
|
||||
verifyingContractAddress: string;
|
||||
}
|
||||
|
Reference in New Issue
Block a user