aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-utils/src/order_factory.ts
blob: 444e5a0b29ed41b9c538410861e0c116ea1e5c28 (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
93
94
95
96
97
98
99
100
import { ECSignature, Order, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Provider } from 'ethereum-types';
import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';

import { constants } from './constants';
import { orderHashUtils } from './order_hash';
import { generatePseudoRandomSalt } from './salt';
import { ecSignOrderHashAsync } from './signature_utils';
import { MessagePrefixType } from './types';

export const orderFactory = {
    createOrder(
        makerAddress: string,
        makerAssetAmount: BigNumber,
        makerAssetData: string,
        takerAssetAmount: BigNumber,
        takerAssetData: string,
        exchangeAddress: string,
        takerAddress: string = constants.NULL_ADDRESS,
        senderAddress: string = constants.NULL_ADDRESS,
        makerFee: BigNumber = constants.ZERO_AMOUNT,
        takerFee: BigNumber = constants.ZERO_AMOUNT,
        feeRecipientAddress: string = constants.NULL_ADDRESS,
        salt: BigNumber = generatePseudoRandomSalt(),
        expirationTimeSeconds: BigNumber = constants.INFINITE_TIMESTAMP_SEC,
    ): Order {
        const order = {
            makerAddress,
            takerAddress,
            senderAddress,
            makerFee,
            takerFee,
            makerAssetAmount,
            takerAssetAmount,
            makerAssetData,
            takerAssetData,
            salt,
            exchangeAddress,
            feeRecipientAddress,
            expirationTimeSeconds,
        };
        return order;
    },
    async createSignedOrderAsync(
        provider: Provider,
        makerAddress: string,
        makerAssetAmount: BigNumber,
        makerAssetData: string,
        takerAssetAmount: BigNumber,
        takerAssetData: string,
        exchangeAddress: string,
        takerAddress?: string,
        senderAddress?: string,
        makerFee?: BigNumber,
        takerFee?: BigNumber,
        feeRecipientAddress?: string,
        salt?: BigNumber,
        expirationTimeSeconds?: BigNumber,
    ): Promise<SignedOrder> {
        const order = orderFactory.createOrder(
            makerAddress,
            makerAssetAmount,
            makerAssetData,
            takerAssetAmount,
            takerAssetData,
            exchangeAddress,
            takerAddress,
            senderAddress,
            makerFee,
            takerFee,
            feeRecipientAddress,
            salt,
            expirationTimeSeconds,
        );
        const orderHash = orderHashUtils.getOrderHashHex(order);
        const messagePrefixOpts = {
            prefixType: MessagePrefixType.EthSign,
            shouldAddPrefixBeforeCallingEthSign: false,
        };
        const ecSignature = await ecSignOrderHashAsync(provider, orderHash, makerAddress, messagePrefixOpts);
        const signature = getVRSHexString(ecSignature);
        const signedOrder: SignedOrder = _.assign(order, { signature });
        return signedOrder;
    },
};

function getVRSHexString(ecSignature: ECSignature): string {
    const ETH_SIGN_SIGNATURE_TYPE = '03';
    const vrs = `${intToHex(ecSignature.v)}${ethUtil.stripHexPrefix(ecSignature.r)}${ethUtil.stripHexPrefix(
        ecSignature.s,
    )}${ETH_SIGN_SIGNATURE_TYPE}`;
    return vrs;
}

function intToHex(i: number): string {
    const hex = ethUtil.bufferToHex(ethUtil.toBuffer(i));
    return hex;
}