aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contract-wrappers/src/contract_wrappers/order_validator_wrapper.ts
blob: a1e02989d4ec76b242601697a8ebc43fc5ca4ca6 (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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import { schemas } from '@0xproject/json-schemas';
import { SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { ContractAbi } from 'ethereum-types';
import * as _ from 'lodash';

import { artifacts } from '../artifacts';
import { BalanceAndAllowance, OrderAndTraderInfo, TraderInfo } from '../types';
import { assert } from '../utils/assert';

import { ContractWrapper } from './contract_wrapper';
import { OrderValidatorContract } from './generated/order_validator';

/**
 * This class includes the functionality related to interacting with the OrderValidator contract.
 */
export class OrderValidatorWrapper extends ContractWrapper {
    public abi: ContractAbi = artifacts.OrderValidator.compilerOutput.abi;
    private _orderValidatorContractIfExists?: OrderValidatorContract;
    /**
     * Instantiate OrderValidatorWrapper
     * @param web3Wrapper Web3Wrapper instance to use
     * @param networkId Desired networkId
     */
    constructor(web3Wrapper: Web3Wrapper, networkId: number) {
        super(web3Wrapper, networkId);
    }
    /**
     * Get an object conforming to OrderAndTraderInfo containing on-chain information of the provided order and address
     * @return  OrderAndTraderInfo
     */
    public async getOrderAndTraderInfoAsync(order: SignedOrder, takerAddress: string): Promise<OrderAndTraderInfo> {
        assert.doesConformToSchema('order', order, schemas.signedOrderSchema);
        assert.isETHAddressHex('takerAddress', takerAddress);
        const OrderValidatorContractInstance = await this._getOrderValidatorContractAsync();
        const orderAndTraderInfo = await OrderValidatorContractInstance.getOrderAndTraderInfo.callAsync(
            order,
            takerAddress,
        );
        const result = {
            orderInfo: orderAndTraderInfo[0],
            traderInfo: orderAndTraderInfo[1],
        };
        return result;
    }
    /**
     * Get an array of objects conforming to OrderAndTraderInfo containing on-chain information of the provided orders and addresses
     * @return  array of OrderAndTraderInfo
     */
    public async getOrdersAndTradersInfoAsync(
        orders: SignedOrder[],
        takerAddresses: string[],
    ): Promise<OrderAndTraderInfo[]> {
        assert.doesConformToSchema('orders', orders, schemas.signedOrdersSchema);
        _.forEach(takerAddresses, (takerAddress, index) =>
            assert.isETHAddressHex(`takerAddresses[${index}]`, takerAddress),
        );
        assert.assert(orders.length === takerAddresses.length, 'Expected orders.length to equal takerAddresses.length');
        const OrderValidatorContractInstance = await this._getOrderValidatorContractAsync();
        const ordersAndTradersInfo = await OrderValidatorContractInstance.getOrdersAndTradersInfo.callAsync(
            orders,
            takerAddresses,
        );
        const orderInfos = ordersAndTradersInfo[0];
        const traderInfos = ordersAndTradersInfo[1];
        const result = _.map(orderInfos, (orderInfo, index) => {
            const traderInfo = traderInfos[index];
            return {
                orderInfo,
                traderInfo,
            };
        });
        return result;
    }
    /**
     * Get an object conforming to TraderInfo containing on-chain balance and allowances for maker and taker of order
     * @return  TraderInfo
     */
    public async getTraderInfoAsync(order: SignedOrder, takerAddress: string): Promise<TraderInfo> {
        assert.doesConformToSchema('order', order, schemas.signedOrderSchema);
        assert.isETHAddressHex('takerAddress', takerAddress);
        const OrderValidatorContractInstance = await this._getOrderValidatorContractAsync();
        const result = await OrderValidatorContractInstance.getTraderInfo.callAsync(order, takerAddress);
        return result;
    }
    /**
     * Get an array of objects conforming to TraderInfo containing on-chain balance and allowances for maker and taker of order
     * @return  array of TraderInfo
     */
    public async getTradersInfoAsync(orders: SignedOrder[], takerAddresses: string[]): Promise<TraderInfo[]> {
        assert.doesConformToSchema('orders', orders, schemas.signedOrdersSchema);
        _.forEach(takerAddresses, (takerAddress, index) =>
            assert.isETHAddressHex(`takerAddresses[${index}]`, takerAddress),
        );
        assert.assert(orders.length === takerAddresses.length, 'Expected orders.length to equal takerAddresses.length');
        const OrderValidatorContractInstance = await this._getOrderValidatorContractAsync();
        const result = await OrderValidatorContractInstance.getTradersInfo.callAsync(orders, takerAddresses);
        return result;
    }
    /**
     * Get an object conforming to BalanceAndAllowance containing on-chain balance and allowance for some address and assetData
     * @return  BalanceAndAllowance
     */
    public async getBalanceAndAllowanceAsync(address: string, assetData: string): Promise<BalanceAndAllowance> {
        assert.isETHAddressHex('address', address);
        assert.isHexString('assetData', assetData);
        const OrderValidatorContractInstance = await this._getOrderValidatorContractAsync();
        const balanceAndAllowance = await OrderValidatorContractInstance.getBalanceAndAllowance.callAsync(
            address,
            assetData,
        );
        const result = {
            balance: balanceAndAllowance[0],
            allowance: balanceAndAllowance[1],
        };
        return result;
    }
    /**
     * Get owner address of tokenId by calling `token.ownerOf(tokenId)`, but returns a null owner instead of reverting on an unowned token.
     * @return  Owner of tokenId or null address if unowned
     */
    public async getERC721TokenOwnerAsync(tokenAddress: string, tokenId: BigNumber): Promise<string | undefined> {
        assert.isETHAddressHex('tokenAddress', tokenAddress);
        assert.isBigNumber('tokenId', tokenId);
        const OrderValidatorContractInstance = await this._getOrderValidatorContractAsync();
        const result = await OrderValidatorContractInstance.getERC721TokenOwner.callAsync(tokenAddress, tokenId);
        return result;
    }
    // HACK: We don't want this method to be visible to the other units within that package but not to the end user.
    // TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused.
    // tslint:disable-next-line:no-unused-variable
    private _invalidateContractInstance(): void {
        delete this._orderValidatorContractIfExists;
    }
    private async _getOrderValidatorContractAsync(): Promise<OrderValidatorContract> {
        if (!_.isUndefined(this._orderValidatorContractIfExists)) {
            return this._orderValidatorContractIfExists;
        }
        const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(artifacts.OrderValidator);
        const contractInstance = new OrderValidatorContract(
            abi,
            address,
            this._web3Wrapper.getProvider(),
            this._web3Wrapper.getContractDefaults(),
        );
        this._orderValidatorContractIfExists = contractInstance;
        return this._orderValidatorContractIfExists;
    }
}