aboutsummaryrefslogtreecommitdiffstats
path: root/packages/asset-buyer/src/standard_relayer_api_asset_buyer_manager.ts
blob: 866bee46e740551d619e73d78281eb215d701d60 (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
import { HttpClient } from '@0xproject/connect';
import { ContractWrappers } from '@0xproject/contract-wrappers';
import { ObjectMap } from '@0xproject/types';
import { Provider } from 'ethereum-types';
import * as _ from 'lodash';

import { AssetBuyer } from './asset_buyer';
import { constants } from './constants';
import { assert } from './utils/assert';
import { assetDataUtils } from './utils/asset_data_utils';

import { OrderProvider, StandardRelayerApiAssetBuyerManagerError } from './types';

// TODO: Read-only list of available assetDatas
export class StandardRelayerAPIAssetBuyerManager {
    // Map of assetData to AssetBuyer for that assetData
    public readonly assetBuyerMap: ObjectMap<AssetBuyer>;
    /**
     * Returns an array of all assetDatas available at the provided sraApiUrl
     * @param   sraApiUrl               The standard relayer API base HTTP url you would like to source orders from.
     * @param   pairedWithAssetData     Optional filter argument to return assetDatas that only pair with this assetData value.
     *
     * @return  An array of all assetDatas available at the provider sraApiUrl
     */
    public static async getAllAvailableAssetDatasAsync(
        sraApiUrl: string,
        pairedWithAssetData?: string,
    ): Promise<string[]> {
        const client = new HttpClient(sraApiUrl);
        const params = {
            assetDataA: pairedWithAssetData,
            perPage: constants.MAX_PER_PAGE,
        };
        const assetPairsResponse = await client.getAssetPairsAsync(params);
        return _.uniq(_.map(assetPairsResponse.records, pairsItem => pairsItem.assetDataB.assetData));
    }
    /**
     * Instantiates a new StandardRelayerAPIAssetBuyerManager instance with all available assetDatas at the provided sraApiUrl
     * @param   provider                The Provider instance you would like to use for interacting with the Ethereum network.
     * @param   sraApiUrl               The standard relayer API base HTTP url you would like to source orders from.
     * @param   orderProvider            An object that conforms to OrderProvider, see type for definition.
     * @param   networkId               The ethereum network id. Defaults to 1 (mainnet).
     * @param   orderRefreshIntervalMs  The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states.
     *                                  Defaults to 10000ms (10s).
     * @return  An promise of an instance of StandardRelayerAPIAssetBuyerManager
     */
    public static async getAssetBuyerManagerWithAllAvailableAssetDatasAsync(
        provider: Provider,
        sraApiUrl: string,
        orderProvider: OrderProvider,
        networkId: number = constants.MAINNET_NETWORK_ID,
        orderRefreshIntervalMs?: number,
    ): Promise<StandardRelayerAPIAssetBuyerManager> {
        const contractWrappers = new ContractWrappers(provider, { networkId });
        const etherTokenAssetData = assetDataUtils.getEtherTokenAssetDataOrThrow(contractWrappers);
        const assetDatas = await StandardRelayerAPIAssetBuyerManager.getAllAvailableAssetDatasAsync(
            sraApiUrl,
            etherTokenAssetData,
        );
        return new StandardRelayerAPIAssetBuyerManager(
            provider,
            assetDatas,
            orderProvider,
            networkId,
            orderRefreshIntervalMs,
        );
    }
    /**
     * Instantiates a new StandardRelayerAPIAssetBuyerManager instance
     * @param   provider                The Provider instance you would like to use for interacting with the Ethereum network.
     * @param   assetDatas              The assetDatas of the desired assets to buy (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
     * @param   orderProvider            An object that conforms to OrderProvider, see type for definition.
     * @param   networkId               The ethereum network id. Defaults to 1 (mainnet).
     * @param   orderRefreshIntervalMs  The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states.
     *                                  Defaults to 10000ms (10s).
     * @return  An instance of StandardRelayerAPIAssetBuyerManager
     */
    constructor(
        provider: Provider,
        assetDatas: string[],
        orderProvider: OrderProvider,
        networkId?: number,
        orderRefreshIntervalMs?: number,
    ) {
        assert.assert(assetDatas.length > 0, `Expected 'assetDatas' to be a non-empty array.`);
        this.assetBuyerMap = _.reduce(
            assetDatas,
            (accAssetBuyerMap: ObjectMap<AssetBuyer>, assetData: string) => {
                accAssetBuyerMap[assetData] = new AssetBuyer(
                    provider,
                    assetData,
                    orderProvider,
                    networkId,
                    orderRefreshIntervalMs,
                );
                return accAssetBuyerMap;
            },
            {},
        );
    }
    /**
     * Get an AssetBuyer for the provided assetData
     * @param   assetData   The desired assetData.
     *
     * @return  An instance of AssetBuyer
     */
    public getAssetBuyerFromAssetData(assetData: string): AssetBuyer {
        const assetBuyer = this.assetBuyerMap[assetData];
        if (_.isUndefined(assetBuyer)) {
            throw new Error(
                `${StandardRelayerApiAssetBuyerManagerError.AssetBuyerNotFound}: For assetData ${assetData}`,
            );
        }
        return assetBuyer;
    }
    /**
     * Get an AssetBuyer for the provided ERC20 tokenAddress
     * @param   tokenAddress    The desired tokenAddress.
     *
     * @return  An instance of AssetBuyer
     */
    public getAssetBuyerFromERC20TokenAddress(tokenAddress: string): AssetBuyer {
        const assetData = assetDataUtils.encodeERC20AssetData(tokenAddress);
        return this.getAssetBuyerFromAssetData(assetData);
    }
}