ccxt 4.2.69 → 4.2.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/build.sh +1 -1
- package/dist/ccxt.browser.js +991 -211
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +3 -1
- package/dist/cjs/src/base/Exchange.js +32 -30
- package/dist/cjs/src/bitget.js +14 -6
- package/dist/cjs/src/coinbase.js +108 -89
- package/dist/cjs/src/digifinex.js +2 -1
- package/dist/cjs/src/gate.js +174 -1
- package/dist/cjs/src/hyperliquid.js +1 -1
- package/dist/cjs/src/kraken.js +1 -0
- package/dist/cjs/src/mexc.js +9 -0
- package/dist/cjs/src/pro/hyperliquid.js +556 -0
- package/js/ccxt.d.ts +4 -1
- package/js/ccxt.js +3 -1
- package/js/src/abstract/coinbase.d.ts +2 -0
- package/js/src/base/Exchange.d.ts +2 -2
- package/js/src/base/Exchange.js +32 -30
- package/js/src/base/types.d.ts +48 -48
- package/js/src/bitget.js +14 -6
- package/js/src/coinbase.d.ts +1 -1
- package/js/src/coinbase.js +108 -89
- package/js/src/digifinex.js +2 -1
- package/js/src/gate.d.ts +4 -1
- package/js/src/gate.js +174 -1
- package/js/src/hyperliquid.js +1 -1
- package/js/src/kraken.js +1 -0
- package/js/src/mexc.js +9 -0
- package/js/src/pro/hyperliquid.d.ts +23 -0
- package/js/src/pro/hyperliquid.js +557 -0
- package/package.json +1 -1
- package/skip-tests.json +49 -58
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
// ----------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
4
|
+
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
5
|
+
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
import hyperliquidRest from '../hyperliquid.js';
|
|
9
|
+
import { ExchangeError } from '../base/errors.js';
|
|
10
|
+
import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
export default class hyperliquid extends hyperliquidRest {
|
|
13
|
+
describe() {
|
|
14
|
+
return this.deepExtend(super.describe(), {
|
|
15
|
+
'has': {
|
|
16
|
+
'ws': true,
|
|
17
|
+
'watchBalance': false,
|
|
18
|
+
'watchMyTrades': true,
|
|
19
|
+
'watchOHLCV': true,
|
|
20
|
+
'watchOrderBook': true,
|
|
21
|
+
'watchOrders': true,
|
|
22
|
+
'watchTicker': false,
|
|
23
|
+
'watchTickers': false,
|
|
24
|
+
'watchTrades': true,
|
|
25
|
+
'watchPosition': false,
|
|
26
|
+
},
|
|
27
|
+
'urls': {
|
|
28
|
+
'api': {
|
|
29
|
+
'ws': {
|
|
30
|
+
'public': 'wss://api.hyperliquid.xyz/ws',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
'test': {
|
|
34
|
+
'ws': {
|
|
35
|
+
'public': 'wss://api.hyperliquid-testnet.xyz/ws',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
'options': {},
|
|
40
|
+
'streaming': {
|
|
41
|
+
'ping': this.ping,
|
|
42
|
+
'keepAlive': 20000,
|
|
43
|
+
},
|
|
44
|
+
'exceptions': {
|
|
45
|
+
'ws': {
|
|
46
|
+
'exact': {},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async watchOrderBook(symbol, limit = undefined, params = {}) {
|
|
52
|
+
/**
|
|
53
|
+
* @method
|
|
54
|
+
* @name hyperliquid#watchOrderBook
|
|
55
|
+
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
56
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
57
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
58
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
59
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
60
|
+
*/
|
|
61
|
+
await this.loadMarkets();
|
|
62
|
+
const market = this.market(symbol);
|
|
63
|
+
symbol = market['symbol'];
|
|
64
|
+
const messageHash = 'orderbook:' + symbol;
|
|
65
|
+
const url = this.urls['api']['ws']['public'];
|
|
66
|
+
const request = {
|
|
67
|
+
'method': 'subscribe',
|
|
68
|
+
'subscription': {
|
|
69
|
+
'type': 'l2Book',
|
|
70
|
+
'coin': market['base'],
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
const message = this.extend(request, params);
|
|
74
|
+
const orderbook = await this.watch(url, messageHash, message, messageHash);
|
|
75
|
+
return orderbook.limit();
|
|
76
|
+
}
|
|
77
|
+
handleOrderBook(client, message) {
|
|
78
|
+
//
|
|
79
|
+
// {
|
|
80
|
+
// "channel": "l2Book",
|
|
81
|
+
// "data": {
|
|
82
|
+
// "coin": "BTC",
|
|
83
|
+
// "time": 1710131872708,
|
|
84
|
+
// "levels": [
|
|
85
|
+
// [
|
|
86
|
+
// {
|
|
87
|
+
// "px": "68674.0",
|
|
88
|
+
// "sz": "0.97139",
|
|
89
|
+
// "n": 4
|
|
90
|
+
// }
|
|
91
|
+
// ],
|
|
92
|
+
// [
|
|
93
|
+
// {
|
|
94
|
+
// "px": "68675.0",
|
|
95
|
+
// "sz": "0.04396",
|
|
96
|
+
// "n": 1
|
|
97
|
+
// }
|
|
98
|
+
// ]
|
|
99
|
+
// ]
|
|
100
|
+
// }
|
|
101
|
+
// }
|
|
102
|
+
//
|
|
103
|
+
const entry = this.safeDict(message, 'data', {});
|
|
104
|
+
const coin = this.safeString(entry, 'coin');
|
|
105
|
+
const marketId = coin + '/USDC:USDC';
|
|
106
|
+
const market = this.market(marketId);
|
|
107
|
+
const symbol = market['symbol'];
|
|
108
|
+
const rawData = this.safeList(entry, 'levels', []);
|
|
109
|
+
const data = {
|
|
110
|
+
'bids': this.safeList(rawData, 0, []),
|
|
111
|
+
'asks': this.safeList(rawData, 1, []),
|
|
112
|
+
};
|
|
113
|
+
const timestamp = this.safeInteger(entry, 'time');
|
|
114
|
+
const snapshot = this.parseOrderBook(data, symbol, timestamp, 'bids', 'asks', 'px', 'sz');
|
|
115
|
+
if (!(symbol in this.orderbooks)) {
|
|
116
|
+
const ob = this.orderBook(snapshot);
|
|
117
|
+
this.orderbooks[symbol] = ob;
|
|
118
|
+
}
|
|
119
|
+
const orderbook = this.orderbooks[symbol];
|
|
120
|
+
orderbook.reset(snapshot);
|
|
121
|
+
const messageHash = 'orderbook:' + symbol;
|
|
122
|
+
client.resolve(orderbook, messageHash);
|
|
123
|
+
}
|
|
124
|
+
async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
125
|
+
/**
|
|
126
|
+
* @method
|
|
127
|
+
* @name hyperliquid#watchMyTrades
|
|
128
|
+
* @description watches information on multiple trades made by the user
|
|
129
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
130
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
131
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
132
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
133
|
+
* @param {string} [params.user] user address, will default to this.walletAddress if not provided
|
|
134
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
|
|
135
|
+
*/
|
|
136
|
+
let userAddress = undefined;
|
|
137
|
+
[userAddress, params] = this.handlePublicAddress('watchMyTrades', params);
|
|
138
|
+
await this.loadMarkets();
|
|
139
|
+
let messageHash = 'myTrades';
|
|
140
|
+
if (symbol !== undefined) {
|
|
141
|
+
symbol = this.symbol(symbol);
|
|
142
|
+
messageHash += ':' + symbol;
|
|
143
|
+
}
|
|
144
|
+
const url = this.urls['api']['ws']['public'];
|
|
145
|
+
const request = {
|
|
146
|
+
'method': 'subscribe',
|
|
147
|
+
'subscription': {
|
|
148
|
+
'type': 'userFills',
|
|
149
|
+
'user': userAddress,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
const message = this.extend(request, params);
|
|
153
|
+
const trades = await this.watch(url, messageHash, message, messageHash);
|
|
154
|
+
if (this.newUpdates) {
|
|
155
|
+
limit = trades.getLimit(symbol, limit);
|
|
156
|
+
}
|
|
157
|
+
return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
|
|
158
|
+
}
|
|
159
|
+
handleMyTrades(client, message) {
|
|
160
|
+
//
|
|
161
|
+
// {
|
|
162
|
+
// "channel": "userFills",
|
|
163
|
+
// "data": {
|
|
164
|
+
// "isSnapshot": true,
|
|
165
|
+
// "user": "0x15f43d1f2dee81424afd891943262aa90f22cc2a",
|
|
166
|
+
// "fills": [
|
|
167
|
+
// {
|
|
168
|
+
// "coin": "BTC",
|
|
169
|
+
// "px": "72528.0",
|
|
170
|
+
// "sz": "0.11693",
|
|
171
|
+
// "side": "A",
|
|
172
|
+
// "time": 1710208712815,
|
|
173
|
+
// "startPosition": "0.11693",
|
|
174
|
+
// "dir": "Close Long",
|
|
175
|
+
// "closedPnl": "-0.81851",
|
|
176
|
+
// "hash": "0xc5adaf35f8402750c218040b0a7bc301130051521273b6f398b3caad3e1f3f5f",
|
|
177
|
+
// "oid": 7484888874,
|
|
178
|
+
// "crossed": true,
|
|
179
|
+
// "fee": "2.968244",
|
|
180
|
+
// "liquidationMarkPx": null,
|
|
181
|
+
// "tid": 567547935839686,
|
|
182
|
+
// "cloid": null
|
|
183
|
+
// }
|
|
184
|
+
// ]
|
|
185
|
+
// }
|
|
186
|
+
// }
|
|
187
|
+
//
|
|
188
|
+
const entry = this.safeDict(message, 'data', {});
|
|
189
|
+
if (this.myTrades === undefined) {
|
|
190
|
+
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
191
|
+
this.myTrades = new ArrayCacheBySymbolById(limit);
|
|
192
|
+
}
|
|
193
|
+
const trades = this.myTrades;
|
|
194
|
+
const symbols = {};
|
|
195
|
+
const data = this.safeList(entry, 'fills', []);
|
|
196
|
+
const dataLength = data.length;
|
|
197
|
+
if (dataLength === 0) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
for (let i = 0; i < data.length; i++) {
|
|
201
|
+
const rawTrade = data[i];
|
|
202
|
+
const parsed = this.parseWsTrade(rawTrade);
|
|
203
|
+
const symbol = parsed['symbol'];
|
|
204
|
+
symbols[symbol] = true;
|
|
205
|
+
trades.append(parsed);
|
|
206
|
+
}
|
|
207
|
+
const keys = Object.keys(symbols);
|
|
208
|
+
for (let i = 0; i < keys.length; i++) {
|
|
209
|
+
const currentMessageHash = 'myTrades:' + keys[i];
|
|
210
|
+
client.resolve(trades, currentMessageHash);
|
|
211
|
+
}
|
|
212
|
+
// non-symbol specific
|
|
213
|
+
const messageHash = 'myTrades';
|
|
214
|
+
client.resolve(trades, messageHash);
|
|
215
|
+
}
|
|
216
|
+
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
217
|
+
/**
|
|
218
|
+
* @method
|
|
219
|
+
* @name hyperliquid#watchTrades
|
|
220
|
+
* @description watches information on multiple trades made in a market
|
|
221
|
+
* @param {string} symbol unified market symbol of the market trades were made in
|
|
222
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
223
|
+
* @param {int} [limit] the maximum number of trade structures to retrieve
|
|
224
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
225
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
|
226
|
+
*/
|
|
227
|
+
await this.loadMarkets();
|
|
228
|
+
const market = this.market(symbol);
|
|
229
|
+
symbol = market['symbol'];
|
|
230
|
+
const messageHash = 'trade:' + symbol;
|
|
231
|
+
const url = this.urls['api']['ws']['public'];
|
|
232
|
+
const request = {
|
|
233
|
+
'method': 'subscribe',
|
|
234
|
+
'subscription': {
|
|
235
|
+
'type': 'trades',
|
|
236
|
+
'coin': market['base'],
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
const message = this.extend(request, params);
|
|
240
|
+
const trades = await this.watch(url, messageHash, message, messageHash);
|
|
241
|
+
if (this.newUpdates) {
|
|
242
|
+
limit = trades.getLimit(symbol, limit);
|
|
243
|
+
}
|
|
244
|
+
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
|
|
245
|
+
}
|
|
246
|
+
handleTrades(client, message) {
|
|
247
|
+
//
|
|
248
|
+
// {
|
|
249
|
+
// "channel": "trades",
|
|
250
|
+
// "data": [
|
|
251
|
+
// {
|
|
252
|
+
// "coin": "BTC",
|
|
253
|
+
// "side": "A",
|
|
254
|
+
// "px": "68517.0",
|
|
255
|
+
// "sz": "0.005",
|
|
256
|
+
// "time": 1710125266669,
|
|
257
|
+
// "hash": "0xc872699f116e012186620407fc08a802015e0097c5cce74710697f7272e6e959",
|
|
258
|
+
// "tid": 981894269203506
|
|
259
|
+
// }
|
|
260
|
+
// ]
|
|
261
|
+
// }
|
|
262
|
+
//
|
|
263
|
+
const entry = this.safeList(message, 'data', []);
|
|
264
|
+
const first = this.safeDict(entry, 0, {});
|
|
265
|
+
const coin = this.safeString(first, 'coin');
|
|
266
|
+
const marketId = coin + '/USDC:USDC';
|
|
267
|
+
const market = this.market(marketId);
|
|
268
|
+
const symbol = market['symbol'];
|
|
269
|
+
if (!(symbol in this.trades)) {
|
|
270
|
+
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
271
|
+
const stored = new ArrayCache(limit);
|
|
272
|
+
this.trades[symbol] = stored;
|
|
273
|
+
}
|
|
274
|
+
const trades = this.trades[symbol];
|
|
275
|
+
for (let i = 0; i < entry.length; i++) {
|
|
276
|
+
const data = this.safeDict(entry, i);
|
|
277
|
+
const trade = this.parseWsTrade(data);
|
|
278
|
+
trades.append(trade);
|
|
279
|
+
}
|
|
280
|
+
const messageHash = 'trade:' + symbol;
|
|
281
|
+
client.resolve(trades, messageHash);
|
|
282
|
+
}
|
|
283
|
+
parseWsTrade(trade, market = undefined) {
|
|
284
|
+
//
|
|
285
|
+
// fetchMyTrades
|
|
286
|
+
//
|
|
287
|
+
// {
|
|
288
|
+
// "coin": "BTC",
|
|
289
|
+
// "px": "72528.0",
|
|
290
|
+
// "sz": "0.11693",
|
|
291
|
+
// "side": "A",
|
|
292
|
+
// "time": 1710208712815,
|
|
293
|
+
// "startPosition": "0.11693",
|
|
294
|
+
// "dir": "Close Long",
|
|
295
|
+
// "closedPnl": "-0.81851",
|
|
296
|
+
// "hash": "0xc5adaf35f8402750c218040b0a7bc301130051521273b6f398b3caad3e1f3f5f",
|
|
297
|
+
// "oid": 7484888874,
|
|
298
|
+
// "crossed": true,
|
|
299
|
+
// "fee": "2.968244",
|
|
300
|
+
// "liquidationMarkPx": null,
|
|
301
|
+
// "tid": 567547935839686,
|
|
302
|
+
// "cloid": null
|
|
303
|
+
// }
|
|
304
|
+
//
|
|
305
|
+
// fetchTrades
|
|
306
|
+
//
|
|
307
|
+
// {
|
|
308
|
+
// "coin": "BTC",
|
|
309
|
+
// "side": "A",
|
|
310
|
+
// "px": "68517.0",
|
|
311
|
+
// "sz": "0.005",
|
|
312
|
+
// "time": 1710125266669,
|
|
313
|
+
// "hash": "0xc872699f116e012186620407fc08a802015e0097c5cce74710697f7272e6e959",
|
|
314
|
+
// "tid": 981894269203506
|
|
315
|
+
// }
|
|
316
|
+
//
|
|
317
|
+
const timestamp = this.safeInteger(trade, 'time');
|
|
318
|
+
const price = this.safeString(trade, 'px');
|
|
319
|
+
const amount = this.safeString(trade, 'sz');
|
|
320
|
+
const coin = this.safeString(trade, 'coin');
|
|
321
|
+
const marketId = coin + '/USDC:USDC';
|
|
322
|
+
market = this.safeMarket(marketId, undefined);
|
|
323
|
+
const symbol = market['symbol'];
|
|
324
|
+
const id = this.safeString(trade, 'tid');
|
|
325
|
+
let side = this.safeString(trade, 'side');
|
|
326
|
+
if (side !== undefined) {
|
|
327
|
+
side = (side === 'A') ? 'sell' : 'buy';
|
|
328
|
+
}
|
|
329
|
+
const fee = this.safeString(trade, 'fee');
|
|
330
|
+
return this.safeTrade({
|
|
331
|
+
'info': trade,
|
|
332
|
+
'timestamp': timestamp,
|
|
333
|
+
'datetime': this.iso8601(timestamp),
|
|
334
|
+
'symbol': symbol,
|
|
335
|
+
'id': id,
|
|
336
|
+
'order': undefined,
|
|
337
|
+
'type': undefined,
|
|
338
|
+
'side': side,
|
|
339
|
+
'takerOrMaker': undefined,
|
|
340
|
+
'price': price,
|
|
341
|
+
'amount': amount,
|
|
342
|
+
'cost': undefined,
|
|
343
|
+
'fee': { 'cost': fee, 'currency': 'USDC' },
|
|
344
|
+
}, market);
|
|
345
|
+
}
|
|
346
|
+
async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
347
|
+
/**
|
|
348
|
+
* @method
|
|
349
|
+
* @name hyperliquid#watchOHLCV
|
|
350
|
+
* @description watches historical candlestick data containing the open, high, low, close price, and the volume of a market
|
|
351
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
352
|
+
* @param {string} timeframe the length of time each candle represents
|
|
353
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
354
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
355
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
356
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
357
|
+
*/
|
|
358
|
+
await this.loadMarkets();
|
|
359
|
+
const market = this.market(symbol);
|
|
360
|
+
symbol = market['symbol'];
|
|
361
|
+
const url = this.urls['api']['ws']['public'];
|
|
362
|
+
const request = {
|
|
363
|
+
'method': 'subscribe',
|
|
364
|
+
'subscription': {
|
|
365
|
+
'type': 'candle',
|
|
366
|
+
'coin': market['base'],
|
|
367
|
+
'interval': timeframe,
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
const messageHash = 'candles:' + timeframe + ':' + symbol;
|
|
371
|
+
const message = this.extend(request, params);
|
|
372
|
+
const ohlcv = await this.watch(url, messageHash, message, messageHash);
|
|
373
|
+
if (this.newUpdates) {
|
|
374
|
+
limit = ohlcv.getLimit(symbol, limit);
|
|
375
|
+
}
|
|
376
|
+
return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
|
|
377
|
+
}
|
|
378
|
+
handleOHLCV(client, message) {
|
|
379
|
+
//
|
|
380
|
+
// {
|
|
381
|
+
// channel: 'candle',
|
|
382
|
+
// data: {
|
|
383
|
+
// t: 1710146280000,
|
|
384
|
+
// T: 1710146339999,
|
|
385
|
+
// s: 'BTC',
|
|
386
|
+
// i: '1m',
|
|
387
|
+
// o: '71400.0',
|
|
388
|
+
// c: '71411.0',
|
|
389
|
+
// h: '71422.0',
|
|
390
|
+
// l: '71389.0',
|
|
391
|
+
// v: '1.20407',
|
|
392
|
+
// n: 20
|
|
393
|
+
// }
|
|
394
|
+
// }
|
|
395
|
+
//
|
|
396
|
+
const data = this.safeDict(message, 'data', {});
|
|
397
|
+
const base = this.safeString(data, 's');
|
|
398
|
+
const symbol = base + '/USDC:USDC';
|
|
399
|
+
const timeframe = this.safeString(data, 'i');
|
|
400
|
+
if (!(symbol in this.ohlcvs)) {
|
|
401
|
+
this.ohlcvs[symbol] = {};
|
|
402
|
+
}
|
|
403
|
+
if (!(timeframe in this.ohlcvs[symbol])) {
|
|
404
|
+
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
405
|
+
const stored = new ArrayCacheByTimestamp(limit);
|
|
406
|
+
this.ohlcvs[symbol][timeframe] = stored;
|
|
407
|
+
}
|
|
408
|
+
const ohlcv = this.ohlcvs[symbol][timeframe];
|
|
409
|
+
const parsed = this.parseOHLCV(data);
|
|
410
|
+
ohlcv.append(parsed);
|
|
411
|
+
const messageHash = 'candles:' + timeframe + ':' + symbol;
|
|
412
|
+
client.resolve(ohlcv, messageHash);
|
|
413
|
+
}
|
|
414
|
+
async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
415
|
+
/**
|
|
416
|
+
* @method
|
|
417
|
+
* @name hyperliquid#watchOrders
|
|
418
|
+
* @description watches information on multiple orders made by the user
|
|
419
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
420
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
421
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
422
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
423
|
+
* @param {string} [params.user] user address, will default to this.walletAddress if not provided
|
|
424
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
|
|
425
|
+
*/
|
|
426
|
+
await this.loadMarkets();
|
|
427
|
+
let userAddress = undefined;
|
|
428
|
+
[userAddress, params] = this.handlePublicAddress('watchOrders', params);
|
|
429
|
+
let market = undefined;
|
|
430
|
+
let messageHash = 'order';
|
|
431
|
+
if (symbol !== undefined) {
|
|
432
|
+
market = this.market(symbol);
|
|
433
|
+
symbol = market['symbol'];
|
|
434
|
+
messageHash = messageHash + ':' + symbol;
|
|
435
|
+
}
|
|
436
|
+
const url = this.urls['api']['ws']['public'];
|
|
437
|
+
const request = {
|
|
438
|
+
'method': 'subscribe',
|
|
439
|
+
'subscription': {
|
|
440
|
+
'type': 'orderUpdates',
|
|
441
|
+
'user': userAddress,
|
|
442
|
+
},
|
|
443
|
+
};
|
|
444
|
+
const message = this.extend(request, params);
|
|
445
|
+
const orders = await this.watch(url, messageHash, message, messageHash);
|
|
446
|
+
if (this.newUpdates) {
|
|
447
|
+
limit = orders.getLimit(symbol, limit);
|
|
448
|
+
}
|
|
449
|
+
return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
|
|
450
|
+
}
|
|
451
|
+
handleOrder(client, message) {
|
|
452
|
+
//
|
|
453
|
+
// {
|
|
454
|
+
// channel: 'orderUpdates',
|
|
455
|
+
// data: [
|
|
456
|
+
// {
|
|
457
|
+
// order: {
|
|
458
|
+
// coin: 'BTC',
|
|
459
|
+
// side: 'B',
|
|
460
|
+
// limitPx: '30000.0',
|
|
461
|
+
// sz: '0.001',
|
|
462
|
+
// oid: 7456484275,
|
|
463
|
+
// timestamp: 1710163596492,
|
|
464
|
+
// origSz: '0.001'
|
|
465
|
+
// },
|
|
466
|
+
// status: 'open',
|
|
467
|
+
// statusTimestamp: 1710163596492
|
|
468
|
+
// }
|
|
469
|
+
// ]
|
|
470
|
+
// }
|
|
471
|
+
//
|
|
472
|
+
const data = this.safeList(message, 'data', []);
|
|
473
|
+
if (this.orders === undefined) {
|
|
474
|
+
const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
|
|
475
|
+
this.orders = new ArrayCacheBySymbolById(limit);
|
|
476
|
+
}
|
|
477
|
+
const dataLength = data.length;
|
|
478
|
+
if (dataLength === 0) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
const stored = this.orders;
|
|
482
|
+
const messageHash = 'order';
|
|
483
|
+
const marketSymbols = {};
|
|
484
|
+
for (let i = 0; i < data.length; i++) {
|
|
485
|
+
const rawOrder = data[i];
|
|
486
|
+
const order = this.parseOrder(rawOrder);
|
|
487
|
+
stored.append(order);
|
|
488
|
+
const symbol = this.safeString(order, 'symbol');
|
|
489
|
+
marketSymbols[symbol] = true;
|
|
490
|
+
}
|
|
491
|
+
const keys = Object.keys(marketSymbols);
|
|
492
|
+
for (let i = 0; i < keys.length; i++) {
|
|
493
|
+
const symbol = keys[i];
|
|
494
|
+
const innerMessageHash = messageHash + ':' + symbol;
|
|
495
|
+
client.resolve(stored, innerMessageHash);
|
|
496
|
+
}
|
|
497
|
+
client.resolve(stored, messageHash);
|
|
498
|
+
}
|
|
499
|
+
handleErrorMessage(client, message) {
|
|
500
|
+
//
|
|
501
|
+
// {
|
|
502
|
+
// "channel": "error",
|
|
503
|
+
// "data": "Error parsing JSON into valid websocket request: { \"type\": \"allMids\" }"
|
|
504
|
+
// }
|
|
505
|
+
//
|
|
506
|
+
const channel = this.safeString(message, 'channel', '');
|
|
507
|
+
const ret_msg = this.safeString(message, 'data', '');
|
|
508
|
+
if (channel === 'error') {
|
|
509
|
+
throw new ExchangeError(this.id + ' ' + ret_msg);
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
handleMessage(client, message) {
|
|
516
|
+
if (this.handleErrorMessage(client, message)) {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
const topic = this.safeString(message, 'channel', '');
|
|
520
|
+
const methods = {
|
|
521
|
+
'pong': this.handlePong,
|
|
522
|
+
'trades': this.handleTrades,
|
|
523
|
+
'l2Book': this.handleOrderBook,
|
|
524
|
+
'candle': this.handleOHLCV,
|
|
525
|
+
'orderUpdates': this.handleOrder,
|
|
526
|
+
'userFills': this.handleMyTrades,
|
|
527
|
+
};
|
|
528
|
+
const exacMethod = this.safeValue(methods, topic);
|
|
529
|
+
if (exacMethod !== undefined) {
|
|
530
|
+
exacMethod.call(this, client, message);
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
const keys = Object.keys(methods);
|
|
534
|
+
for (let i = 0; i < keys.length; i++) {
|
|
535
|
+
const key = keys[i];
|
|
536
|
+
if (topic.indexOf(keys[i]) >= 0) {
|
|
537
|
+
const method = methods[key];
|
|
538
|
+
method.call(this, client, message);
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
ping(client) {
|
|
544
|
+
return {
|
|
545
|
+
'method': 'ping',
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
handlePong(client, message) {
|
|
549
|
+
//
|
|
550
|
+
// {
|
|
551
|
+
// "channel": "pong"
|
|
552
|
+
// }
|
|
553
|
+
//
|
|
554
|
+
client.lastPong = this.safeInteger(message, 'pong');
|
|
555
|
+
return message;
|
|
556
|
+
}
|
|
557
|
+
}
|
package/package.json
CHANGED