aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-utils/src/eip712_utils.ts
blob: 685fdc8c841c3ad247d72cee1a04575253909b38 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { assert } from '@0x/assert';
import { schemas } from '@0x/json-schemas';
import {
    EIP712DomainWithDefaultSchema,
    EIP712Object,
    EIP712TypedData,
    EIP712Types,
    Order,
    ZeroExTransaction,
} from '@0x/types';
import * as _ from 'lodash';

import { constants } from './constants';

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   domain Domain containing a name (optional), version (optional), and verifying contract address
     * @return  A typed data object
     */
    createTypedData: (
        primaryType: string,
        types: EIP712Types,
        message: EIP712Object,
        domain: EIP712DomainWithDefaultSchema,
    ): EIP712TypedData => {
        assert.isETHAddressHex('verifyingContractAddress', domain.verifyingContractAddress);
        assert.isString('primaryType', primaryType);
        const typedData = {
            types: {
                EIP712Domain: constants.DEFAULT_DOMAIN_SCHEMA.parameters,
                ...types,
            },
            domain: {
                name: _.isUndefined(domain.name) ? constants.EXCHANGE_DOMAIN_NAME : domain.name,
                version: _.isUndefined(domain.version) ? constants.EXCHANGE_DOMAIN_VERSION : domain.version,
                verifyingContract: domain.verifyingContractAddress,
            },
            message,
            primaryType,
        };
        assert.doesConformToSchema('typedData', typedData, schemas.eip712TypedDataSchema);
        return typedData;
    },
    /**
     * Creates an Order EIP712TypedData object for use with signTypedData.
     * @param   Order the order
     * @return  A typed data object
     */
    createOrderTypedData: (order: Order): EIP712TypedData => {
        assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]);
        const normalizedOrder = _.mapValues(order, value => {
            return !_.isString(value) ? value.toString() : value;
        });
        const domain = {
            verifyingContractAddress: order.exchangeAddress,
        };
        const typedData = eip712Utils.createTypedData(
            constants.EXCHANGE_ORDER_SCHEMA.name,
            { Order: constants.EXCHANGE_ORDER_SCHEMA.parameters },
            normalizedOrder,
            domain,
        );
        return typedData;
    },
    /**
     * Creates an ExecuteTransaction EIP712TypedData object for use with signTypedData and
     * 0x Exchange executeTransaction.
     * @param   ZeroExTransaction the 0x transaction
     * @return  A typed data object
     */
    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.EXCHANGE_ZEROEX_TRANSACTION_SCHEMA.name,
            { ZeroExTransaction: constants.EXCHANGE_ZEROEX_TRANSACTION_SCHEMA.parameters },
            normalizedTransaction,
            domain,
        );
        return typedData;
    },
};