aboutsummaryrefslogtreecommitdiffstats
path: root/packages/asset-buyer/src/forwarder_helper_factory.ts
blob: 4c4adfda07944b91edc0a07cc6a70b2e72e88905 (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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
// import { assert } from '@0xproject/assert';
// import { APIOrder, HttpClient, OrderbookResponse } from '@0xproject/connect';
// import { ContractWrappers, OrderAndTraderInfo, OrderStatus } from '@0xproject/contract-wrappers';
// import { schemas } from '@0xproject/json-schemas';
// import { assetDataUtils } from '@0xproject/order-utils';
// import { RemainingFillableCalculator } from '@0xproject/order-utils/lib/src/remaining_fillable_calculator';
// import { RPCSubprovider, Web3ProviderEngine } from '@0xproject/subproviders';
// import { SignedOrder } from '@0xproject/types';
// import { BigNumber } from '@0xproject/utils';
// import * as _ from 'lodash';

// import { constants } from './constants';
// import { ForwarderHelperImpl, ForwarderHelperImplConfig } from '@0xproject/asset-buyer/src/asset_buyer';
// import { ForwarderHelper, ForwarderHelperFactoryError } from './types';
// import { orderUtils } from './utils/order_utils';

// export const forwarderHelperFactory = {
//     /**
//      * Given an array of orders and an array of feeOrders, get a ForwarderHelper
//      * @param   orders      An array of objects conforming to SignedOrder. Each order should specify the same makerAssetData and takerAssetData
//      * @param   feeOrders   An array of objects conforming to SignedOrder. Each order should specify ZRX as makerAssetData WETH as takerAssetData
//      * @return  A ForwarderHelper, see type for definition
//      */
//     getForwarderHelperForOrders(orders: SignedOrder[], feeOrders: SignedOrder[] = []): ForwarderHelper {
//         assert.doesConformToSchema('orders', orders, schemas.signedOrdersSchema);
//         assert.doesConformToSchema('feeOrders', orders, schemas.signedOrdersSchema);
//         // TODO: Add assertion here for orders all having the same makerAsset and takerAsset
//         const config: ForwarderHelperImplConfig = {
//             orders,
//             feeOrders,
//         };
//         const helper = new ForwarderHelperImpl(config);
//         return helper;
//     },
//     /**
//      * Given a desired makerAsset and SRA url, get a ForwarderHelper
//      * @param   makerAssetData      An array of objects conforming to SignedOrder. Each order should specify the same makerAssetData and takerAssetData
//      * @param   sraUrl              A url pointing to an SRA v2 compliant endpoint.
//      * @param   rpcUrl              A url pointing to an ethereum node.
//      * @param   networkId           The ethereum networkId, defaults to 1 (mainnet).
//      * @return  A ForwarderHelper, see type for definition
//      */
//     async getForwarderHelperForMakerAssetDataAsync(
//         makerAssetData: string,
//         sraUrl: string,
//         rpcUrl?: string,
//         networkId: number = 1,
//     ): Promise<ForwarderHelper> {
//         assert.isHexString('makerAssetData', makerAssetData);
//         assert.isWebUri('sraUrl', sraUrl);
//         if (!_.isUndefined(rpcUrl)) {
//             assert.isWebUri('rpcUrl', rpcUrl);
//         }
//         assert.isNumber('networkId', networkId);
//         // create provider
//         const providerEngine = new Web3ProviderEngine();
//         if (!_.isUndefined(rpcUrl)) {
//             providerEngine.addProvider(new RPCSubprovider(rpcUrl));
//         }
//         providerEngine.start();
//         // create contract wrappers given provider and networkId
//         const contractWrappers = new ContractWrappers(providerEngine, { networkId });
//         // find ether token asset data
//         const etherTokenAddressIfExists = contractWrappers.etherToken.getContractAddressIfExists();
//         if (_.isUndefined(etherTokenAddressIfExists)) {
//             throw new Error(ForwarderHelperFactoryError.NoEtherTokenContractFound);
//         }
//         const etherTokenAssetData = assetDataUtils.encodeERC20AssetData(etherTokenAddressIfExists);
//         // find zrx token asset data
//         let zrxTokenAssetData: string;
//         try {
//             zrxTokenAssetData = contractWrappers.exchange.getZRXAssetData();
//         } catch (err) {
//             throw new Error(ForwarderHelperFactoryError.NoZrxTokenContractFound);
//         }
//         // get orderbooks for makerAsset/WETH and ZRX/WETH
//         const sraClient = new HttpClient(sraUrl);
//         const orderbookRequests = [
//             { baseAssetData: makerAssetData, quoteAssetData: etherTokenAssetData },
//             { baseAssetData: zrxTokenAssetData, quoteAssetData: etherTokenAssetData },
//         ];
//         const requestOpts = { networkId };
//         let makerAssetOrderbook: OrderbookResponse;
//         let zrxOrderbook: OrderbookResponse;
//         try {
//             [makerAssetOrderbook, zrxOrderbook] = await Promise.all(
//                 _.map(orderbookRequests, request => sraClient.getOrderbookAsync(request, requestOpts)),
//             );
//         } catch (err) {
//             throw new Error(ForwarderHelperFactoryError.StandardRelayerApiError);
//         }

//         // validate orders and find remaining fillable from on chain state or sra api
//         let ordersAndRemainingFillableMakerAssetAmounts: OrdersAndRemainingFillableMakerAssetAmounts;
//         let feeOrdersAndRemainingFillableMakerAssetAmounts: OrdersAndRemainingFillableMakerAssetAmounts;
//         if (!_.isUndefined(rpcUrl)) {
//             // if we do have an rpc url, get on-chain orders and traders info via the OrderValidatorWrapper
//             const ordersFromSra = getOpenAsksFromOrderbook(makerAssetOrderbook);
//             const feeOrdersFromSra = getOpenAsksFromOrderbook(zrxOrderbook);
//             // TODO: try catch these requests and throw a more domain specific error
//             // TODO: optimization, reduce this to once RPC call buy combining orders into one array and then splitting up the response
//             const [makerAssetOrdersAndTradersInfo, feeOrdersAndTradersInfo] = await Promise.all(
//                 _.map([ordersFromSra, feeOrdersFromSra], ordersToBeValidated => {
//                     const takerAddresses = _.map(ordersToBeValidated, () => constants.NULL_ADDRESS);
//                     return contractWrappers.orderValidator.getOrdersAndTradersInfoAsync(
//                         ordersToBeValidated,
//                         takerAddresses,
//                     );
//                 }),
//             );
//             // take maker asset orders from SRA + on chain information and find the valid orders and remaining fillable maker asset amounts
//             ordersAndRemainingFillableMakerAssetAmounts = getValidOrdersAndRemainingFillableMakerAssetAmountsFromOnChain(
//                 ordersFromSra,
//                 makerAssetOrdersAndTradersInfo,
//                 zrxTokenAssetData,
//             );
//             // take fee orders from SRA + on chain information and find the valid orders and remaining fillable maker asset amounts
//             feeOrdersAndRemainingFillableMakerAssetAmounts = getValidOrdersAndRemainingFillableMakerAssetAmountsFromOnChain(
//                 feeOrdersFromSra,
//                 feeOrdersAndTradersInfo,
//                 zrxTokenAssetData,
//             );
//         } else {
//             // if we don't have an rpc url, assume all orders are valid and fallback to optional fill amounts from SRA
//             // if fill amounts are not available from the SRA, assume all orders are completely fillable
//             const apiOrdersFromSra = makerAssetOrderbook.asks.records;
//             const feeApiOrdersFromSra = zrxOrderbook.asks.records;
//             // take maker asset orders from SRA and the valid orders and remaining fillable maker asset amounts
//             ordersAndRemainingFillableMakerAssetAmounts = getValidOrdersAndRemainingFillableMakerAssetAmountsFromApi(
//                 apiOrdersFromSra,
//             );
//             // take fee orders from SRA and find the valid orders and remaining fillable maker asset amounts
//             feeOrdersAndRemainingFillableMakerAssetAmounts = getValidOrdersAndRemainingFillableMakerAssetAmountsFromApi(
//                 feeApiOrdersFromSra,
//             );
//         }
//         // compile final config
//         const config: ForwarderHelperImplConfig = {
//             orders: ordersAndRemainingFillableMakerAssetAmounts.orders,
//             feeOrders: feeOrdersAndRemainingFillableMakerAssetAmounts.orders,
//             remainingFillableMakerAssetAmounts:
//                 ordersAndRemainingFillableMakerAssetAmounts.remainingFillableMakerAssetAmounts,
//             remainingFillableFeeAmounts:
//                 feeOrdersAndRemainingFillableMakerAssetAmounts.remainingFillableMakerAssetAmounts,
//         };
//         const helper = new ForwarderHelperImpl(config);
//         return helper;
//     },
// };

// interface OrdersAndRemainingFillableMakerAssetAmounts {
//     orders: SignedOrder[];
//     remainingFillableMakerAssetAmounts: BigNumber[];
// }

// /**
//  * Given an array of APIOrder objects from a standard relayer api, return an array
//  * of fillable orders with their corresponding remainingFillableMakerAssetAmounts
//  */
// function getValidOrdersAndRemainingFillableMakerAssetAmountsFromApi(
//     apiOrders: APIOrder[],
// ): OrdersAndRemainingFillableMakerAssetAmounts {
//     const result = _.reduce(
//         apiOrders,
//         (acc, apiOrder) => {
//             // get current accumulations
//             const { orders, remainingFillableMakerAssetAmounts } = acc;
//             // get order and metadata
//             const { order, metaData } = apiOrder;
//             // if the order is expired or not open, move on
//             if (orderUtils.isOrderExpired(order) || !orderUtils.isOpenOrder(order)) {
//                 return acc;
//             }
//             // calculate remainingFillableMakerAssetAmount from api metadata, else assume order is completely fillable
//             const remainingFillableTakerAssetAmount = _.get(
//                 metaData,
//                 'remainingTakerAssetAmount',
//                 order.takerAssetAmount,
//             );
//             const remainingFillableMakerAssetAmount = orderUtils.calculateRemainingMakerAssetAmount(
//                 order,
//                 remainingFillableTakerAssetAmount,
//             );
//             // if there is some amount of maker asset left to fill and add the order and remaining amount to the accumulations
//             // if there is not any maker asset left to fill, do not add
//             if (remainingFillableMakerAssetAmount.gt(constants.ZERO_AMOUNT)) {
//                 return {
//                     orders: _.concat(orders, order),
//                     remainingFillableMakerAssetAmounts: _.concat(
//                         remainingFillableMakerAssetAmounts,
//                         remainingFillableMakerAssetAmount,
//                     ),
//                 };
//             } else {
//                 return acc;
//             }
//         },
//         { orders: [] as SignedOrder[], remainingFillableMakerAssetAmounts: [] as BigNumber[] },
//     );
//     return result;
// }

// /**
//  * Given an array of orders and corresponding on-chain infos, return a subset of the orders
//  * that are still fillable orders with their corresponding remainingFillableMakerAssetAmounts
//  */
// function getValidOrdersAndRemainingFillableMakerAssetAmountsFromOnChain(
//     inputOrders: SignedOrder[],
//     ordersAndTradersInfo: OrderAndTraderInfo[],
//     zrxAssetData: string,
// ): OrdersAndRemainingFillableMakerAssetAmounts {
//     // iterate through the input orders and find the ones that are still fillable
//     // for the orders that are still fillable, calculate the remaining fillable maker asset amount
//     const result = _.reduce(
//         inputOrders,
//         (acc, order, index) => {
//             // get current accumulations
//             const { orders, remainingFillableMakerAssetAmounts } = acc;
//             // get corresponding on-chain state for the order
//             const { orderInfo, traderInfo } = ordersAndTradersInfo[index];
//             // if the order IS NOT fillable, do not add anything to the accumulations and continue iterating
//             if (orderInfo.orderStatus !== OrderStatus.FILLABLE) {
//                 return acc;
//             }
//             // if the order IS fillable, add the order and calculate the remaining fillable amount
//             const transferrableAssetAmount = BigNumber.min([traderInfo.makerAllowance, traderInfo.makerBalance]);
//             const transferrableFeeAssetAmount = BigNumber.min([
//                 traderInfo.makerZrxAllowance,
//                 traderInfo.makerZrxBalance,
//             ]);
//             const remainingTakerAssetAmount = order.takerAssetAmount.minus(orderInfo.orderTakerAssetFilledAmount);
//             const remainingMakerAssetAmount = orderUtils.calculateRemainingMakerAssetAmount(
//                 order,
//                 remainingTakerAssetAmount,
//             );
//             const remainingFillableCalculator = new RemainingFillableCalculator(
//                 order.makerFee,
//                 order.makerAssetAmount,
//                 order.makerAssetData === zrxAssetData,
//                 transferrableAssetAmount,
//                 transferrableFeeAssetAmount,
//                 remainingMakerAssetAmount,
//             );
//             const remainingFillableAmount = remainingFillableCalculator.computeRemainingFillable();
//             return {
//                 orders: _.concat(orders, order),
//                 remainingFillableMakerAssetAmounts: _.concat(
//                     remainingFillableMakerAssetAmounts,
//                     remainingFillableAmount,
//                 ),
//             };
//         },
//         { orders: [] as SignedOrder[], remainingFillableMakerAssetAmounts: [] as BigNumber[] },
//     );
//     return result;
// }

// function getOpenAsksFromOrderbook(orderbookResponse: OrderbookResponse): SignedOrder[] {
//     const asks = _.map(orderbookResponse.asks.records, apiOrder => apiOrder.order);
//     const result = _.filter(asks, ask => orderUtils.isOpenOrder(ask));
//     return result;
// }